@proto-kit/protocol 0.1.1-develop.340 → 0.1.1-develop.456
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/dist/blockmodules/AccountStateModule.d.ts +1 -1
- package/dist/blockmodules/AccountStateModule.d.ts.map +1 -1
- package/dist/blockmodules/BlockHeightHook.d.ts +7 -0
- package/dist/blockmodules/BlockHeightHook.d.ts.map +1 -0
- package/dist/blockmodules/BlockHeightHook.js +16 -0
- package/dist/blockmodules/NoopBlockHook.d.ts +7 -0
- package/dist/blockmodules/NoopBlockHook.d.ts.map +1 -0
- package/dist/blockmodules/NoopBlockHook.js +9 -0
- package/dist/blockmodules/NoopTransactionHook.d.ts +1 -1
- package/dist/blockmodules/NoopTransactionHook.d.ts.map +1 -1
- package/dist/blockmodules/NoopTransactionHook.js +1 -2
- package/dist/hooks/AccountStateHook.d.ts +38 -0
- package/dist/hooks/AccountStateHook.d.ts.map +1 -0
- package/dist/hooks/AccountStateHook.js +36 -0
- package/dist/hooks/BlockHeightHook.d.ts +7 -0
- package/dist/hooks/BlockHeightHook.d.ts.map +1 -0
- package/dist/hooks/BlockHeightHook.js +14 -0
- package/dist/hooks/NoopBlockHook.d.ts +7 -0
- package/dist/hooks/NoopBlockHook.d.ts.map +1 -0
- package/dist/hooks/NoopBlockHook.js +9 -0
- package/dist/hooks/NoopTransactionHook.d.ts +6 -0
- package/dist/hooks/NoopTransactionHook.d.ts.map +1 -0
- package/dist/hooks/NoopTransactionHook.js +4 -0
- package/dist/hooks/TransactionFeeHook.d.ts +16 -0
- package/dist/hooks/TransactionFeeHook.d.ts.map +1 -0
- package/dist/hooks/TransactionFeeHook.js +39 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/model/Option.d.ts +29 -22
- package/dist/model/Option.d.ts.map +1 -1
- package/dist/model/Option.js +51 -45
- package/dist/model/StateTransition.d.ts +4 -2
- package/dist/model/StateTransition.d.ts.map +1 -1
- package/dist/model/StateTransition.js +2 -2
- package/dist/model/network/NetworkState.d.ts +1 -40
- package/dist/model/network/NetworkState.d.ts.map +1 -1
- package/dist/model/network/NetworkState.js +9 -10
- package/dist/protocol/Protocol.d.ts +4 -18
- package/dist/protocol/Protocol.d.ts.map +1 -1
- package/dist/protocol/Protocol.js +20 -9
- package/dist/protocol/ProtocolModule.d.ts +2 -2
- package/dist/protocol/ProtocolModule.d.ts.map +1 -1
- package/dist/protocol/ProtocolModule.js +1 -1
- package/dist/protocol/ProvableBlockHook.d.ts +16 -0
- package/dist/protocol/ProvableBlockHook.d.ts.map +1 -0
- package/dist/protocol/ProvableBlockHook.js +4 -0
- package/dist/protocol/ProvableTransactionHook.d.ts +2 -1
- package/dist/protocol/ProvableTransactionHook.d.ts.map +1 -1
- package/dist/protocol/TransitioningProtocolModule.d.ts +4 -0
- package/dist/protocol/TransitioningProtocolModule.d.ts.map +1 -1
- package/dist/protocol/TransitioningProtocolModule.js +4 -0
- package/dist/prover/block/BlockProvable.d.ts +21 -6
- package/dist/prover/block/BlockProvable.d.ts.map +1 -1
- package/dist/prover/block/BlockProvable.js +3 -1
- package/dist/prover/block/BlockProver.d.ts +9 -4
- package/dist/prover/block/BlockProver.d.ts.map +1 -1
- package/dist/prover/block/BlockProver.js +66 -16
- package/dist/prover/block/BlockTransactionPosition.d.ts +36 -0
- package/dist/prover/block/BlockTransactionPosition.d.ts.map +1 -0
- package/dist/prover/block/BlockTransactionPosition.js +25 -0
- package/dist/prover/statetransition/StateTransitionProver.d.ts +1 -1
- package/dist/prover/statetransition/StateTransitionProver.d.ts.map +1 -1
- package/dist/prover/statetransition/StateTransitionProver.js +4 -5
- package/dist/prover/statetransition/StateTransitionWitnessProvider.d.ts +3 -3
- package/dist/prover/statetransition/StateTransitionWitnessProvider.d.ts.map +1 -1
- package/dist/prover/statetransition/StateTransitionWitnessProvider.js +2 -2
- package/dist/state/State.d.ts +8 -1
- package/dist/state/State.d.ts.map +1 -1
- package/dist/state/State.js +11 -4
- package/dist/state/StateServiceProvider.d.ts +0 -2
- package/dist/state/StateServiceProvider.d.ts.map +1 -1
- package/dist/state/StateServiceProvider.js +5 -17
- package/package.json +3 -2
- package/src/blockmodules/AccountStateModule.ts +2 -2
- package/src/blockmodules/BlockHeightHook.ts +21 -0
- package/src/blockmodules/NoopBlockHook.ts +16 -0
- package/src/blockmodules/NoopTransactionHook.ts +3 -4
- package/src/index.ts +4 -4
- package/src/model/Option.ts +71 -56
- package/src/model/StateTransition.ts +2 -2
- package/src/model/network/NetworkState.ts +9 -9
- package/src/protocol/Protocol.ts +33 -32
- package/src/protocol/ProtocolModule.ts +3 -3
- package/src/protocol/ProvableBlockHook.ts +22 -0
- package/src/protocol/ProvableTransactionHook.ts +4 -1
- package/src/protocol/TransitioningProtocolModule.ts +4 -0
- package/src/prover/block/BlockProvable.ts +4 -2
- package/src/prover/block/BlockProver.ts +134 -21
- package/src/prover/block/BlockTransactionPosition.ts +34 -0
- package/src/prover/statetransition/StateTransitionProver.ts +6 -13
- package/src/prover/statetransition/StateTransitionWitnessProvider.ts +4 -5
- package/src/state/State.ts +11 -4
- package/src/state/StateServiceProvider.ts +2 -10
- package/test/Option.test.ts +64 -0
- package/test/StateTransition.test.ts +1 -1
- package/dist/utils/merkletree/InMemoryMerkleTreeStorage.d.ts +0 -11
- package/dist/utils/merkletree/InMemoryMerkleTreeStorage.d.ts.map +0 -1
- package/dist/utils/merkletree/InMemoryMerkleTreeStorage.js +0 -12
- package/dist/utils/merkletree/MerkleTreeStore.d.ts +0 -11
- package/dist/utils/merkletree/MerkleTreeStore.d.ts.map +0 -1
- package/dist/utils/merkletree/MerkleTreeStore.js +0 -1
- package/dist/utils/merkletree/RollupMerkleTree.d.ts +0 -132
- package/dist/utils/merkletree/RollupMerkleTree.d.ts.map +0 -1
- package/dist/utils/merkletree/RollupMerkleTree.js +0 -251
- package/src/utils/merkletree/InMemoryMerkleTreeStorage.ts +0 -17
- package/src/utils/merkletree/MerkleTreeStore.ts +0 -15
- package/src/utils/merkletree/RollupMerkleTree.ts +0 -275
- package/src/utils/merkletree/VirtualMerkleTreeStore.ts +0 -21
- package/test/utils/MerkleTree.test.ts +0 -82
package/src/model/Option.ts
CHANGED
|
@@ -17,10 +17,67 @@ export class ProvableOption extends Struct({
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
export abstract class OptionBase {
|
|
21
|
+
protected constructor(public isSome: Bool, public isForcedSome: Bool) {}
|
|
22
|
+
|
|
23
|
+
protected abstract encodeValueToFields(): Field[];
|
|
24
|
+
|
|
25
|
+
protected abstract clone(): OptionBase;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @returns Tree representation of the current value
|
|
29
|
+
*/
|
|
30
|
+
public get treeValue() {
|
|
31
|
+
const treeValue = Poseidon.hash(this.encodeValueToFields());
|
|
32
|
+
|
|
33
|
+
return Provable.if(
|
|
34
|
+
this.isSome.and(this.isForcedSome.not()),
|
|
35
|
+
treeValue,
|
|
36
|
+
Field(0)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public forceSome() {
|
|
41
|
+
this.isForcedSome = Provable.if(this.isSome, Bool(false), Bool(true));
|
|
42
|
+
this.isSome = Bool(true);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns the `to`-value as decoded as a list of fields
|
|
47
|
+
* Not in circuit
|
|
48
|
+
*/
|
|
49
|
+
public toFields(): Field[] {
|
|
50
|
+
if (this.isSome.toBoolean()) {
|
|
51
|
+
return this.encodeValueToFields();
|
|
52
|
+
}
|
|
53
|
+
return [Field(0)];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @returns Provable representation of the current option.
|
|
58
|
+
*/
|
|
59
|
+
public toProvable() {
|
|
60
|
+
return new ProvableOption({
|
|
61
|
+
isSome: this.isSome,
|
|
62
|
+
value: this.treeValue,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public toJSON() {
|
|
67
|
+
const value = this.encodeValueToFields().map((field) => field.toString());
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
isSome: this.isSome.toBoolean(),
|
|
71
|
+
isForcedSome: this.isForcedSome.toBoolean(),
|
|
72
|
+
value,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
20
77
|
/**
|
|
21
78
|
* Option facilitating in-circuit values that may or may not exist.
|
|
22
79
|
*/
|
|
23
|
-
export class Option<Value> {
|
|
80
|
+
export class Option<Value> extends OptionBase {
|
|
24
81
|
/**
|
|
25
82
|
* Creates a new Option from the provided parameters
|
|
26
83
|
*
|
|
@@ -58,57 +115,28 @@ export class Option<Value> {
|
|
|
58
115
|
return new Option(Bool(false), Field(0), Field);
|
|
59
116
|
}
|
|
60
117
|
|
|
61
|
-
public isForcedSome = Bool(false);
|
|
62
|
-
|
|
63
118
|
public constructor(
|
|
64
|
-
|
|
119
|
+
isSome: Bool,
|
|
65
120
|
public value: Value,
|
|
66
|
-
public valueType: FlexibleProvablePure<Value
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return new Option(this.isSome, this.value, this.valueType);
|
|
121
|
+
public valueType: FlexibleProvablePure<Value>,
|
|
122
|
+
isForcedSome = Bool(false)
|
|
123
|
+
) {
|
|
124
|
+
super(isSome, isForcedSome);
|
|
71
125
|
}
|
|
72
126
|
|
|
73
|
-
public
|
|
74
|
-
this.
|
|
75
|
-
this.isSome = Bool(true);
|
|
127
|
+
public encodeValueToFields(): Field[] {
|
|
128
|
+
return this.valueType.toFields(this.value);
|
|
76
129
|
}
|
|
77
130
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return Provable.if(
|
|
85
|
-
this.isSome.and(this.isForcedSome.not()),
|
|
86
|
-
treeValue,
|
|
87
|
-
Field(0)
|
|
131
|
+
public clone(): Option<Value> {
|
|
132
|
+
return new Option(
|
|
133
|
+
this.isSome,
|
|
134
|
+
this.value,
|
|
135
|
+
this.valueType,
|
|
136
|
+
this.isForcedSome
|
|
88
137
|
);
|
|
89
138
|
}
|
|
90
139
|
|
|
91
|
-
/**
|
|
92
|
-
* Returns the `to`-value as decoded as a list of fields
|
|
93
|
-
* Not in circuit
|
|
94
|
-
*/
|
|
95
|
-
public toFields(): Field[] {
|
|
96
|
-
if (this.isSome.toBoolean()) {
|
|
97
|
-
return this.valueType.toFields(this.value);
|
|
98
|
-
}
|
|
99
|
-
return [Field(0)];
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* @returns Provable representation of the current option.
|
|
104
|
-
*/
|
|
105
|
-
public toProvable() {
|
|
106
|
-
return new ProvableOption({
|
|
107
|
-
isSome: this.isSome,
|
|
108
|
-
value: this.treeValue,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
140
|
/**
|
|
113
141
|
* @returns Returns the value of this option if it isSome,
|
|
114
142
|
* otherwise returns the given defaultValue
|
|
@@ -121,17 +149,4 @@ export class Option<Value> {
|
|
|
121
149
|
defaultValue
|
|
122
150
|
);
|
|
123
151
|
}
|
|
124
|
-
|
|
125
|
-
public toJSON() {
|
|
126
|
-
const valueContent = this.valueType
|
|
127
|
-
.toFields(this.value)
|
|
128
|
-
.map((field) => field.toString())
|
|
129
|
-
.reduce((a, b) => `${a}, ${b}`);
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
isSome: this.isSome.toBoolean(),
|
|
133
|
-
|
|
134
|
-
value: `[${valueContent}]`,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
152
|
}
|
|
@@ -4,18 +4,18 @@ export class CurrentBlock extends Struct({
|
|
|
4
4
|
height: UInt64,
|
|
5
5
|
}) {}
|
|
6
6
|
|
|
7
|
-
export class PreviousBlock extends Struct({
|
|
8
|
-
rootHash: Field,
|
|
9
|
-
}) {}
|
|
10
|
-
|
|
11
7
|
export class NetworkState extends Struct({
|
|
12
8
|
block: CurrentBlock,
|
|
13
|
-
previous: PreviousBlock,
|
|
14
9
|
}) {
|
|
15
10
|
public hash(): Field {
|
|
16
|
-
return Poseidon.hash(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
return Poseidon.hash(CurrentBlock.toFields(this.block));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public static empty(){
|
|
15
|
+
return new NetworkState({
|
|
16
|
+
block: {
|
|
17
|
+
height: UInt64.zero,
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
20
|
}
|
|
21
21
|
}
|
package/src/protocol/Protocol.ts
CHANGED
|
@@ -22,15 +22,23 @@ import { ProvableTransactionHook } from "./ProvableTransactionHook";
|
|
|
22
22
|
import { NoopTransactionHook } from "../blockmodules/NoopTransactionHook";
|
|
23
23
|
import { ProtocolEnvironment } from "./ProtocolEnvironment";
|
|
24
24
|
import { AccountStateModule } from "../blockmodules/AccountStateModule";
|
|
25
|
+
import { ProvableBlockHook } from "./ProvableBlockHook";
|
|
26
|
+
import { NoopBlockHook } from "../blockmodules/NoopBlockHook";
|
|
27
|
+
import { BlockHeightHook } from "../blockmodules/BlockHeightHook";
|
|
28
|
+
|
|
29
|
+
const PROTOCOL_INJECTION_TOKENS = {
|
|
30
|
+
ProvableTransactionHook: "ProvableTransactionHook",
|
|
31
|
+
ProvableBlockHook: "ProvableBlockHook",
|
|
32
|
+
};
|
|
25
33
|
|
|
26
34
|
export type GenericProtocolModuleRecord = ModulesRecord<
|
|
27
35
|
TypedClass<ProtocolModule<unknown>>
|
|
28
36
|
>;
|
|
29
37
|
|
|
30
|
-
interface BlockProverType extends ProtocolModule
|
|
38
|
+
interface BlockProverType extends ProtocolModule, BlockProvable {}
|
|
31
39
|
|
|
32
40
|
interface StateTransitionProverType
|
|
33
|
-
extends ProtocolModule
|
|
41
|
+
extends ProtocolModule,
|
|
34
42
|
StateTransitionProvable {}
|
|
35
43
|
|
|
36
44
|
export interface ProtocolCustomModulesRecord {
|
|
@@ -126,67 +134,60 @@ export class Protocol<Modules extends ProtocolModulesRecord>
|
|
|
126
134
|
// Register the BlockModules seperately since we need to
|
|
127
135
|
// inject them differently later
|
|
128
136
|
let atLeastOneTransactionHookRegistered = false;
|
|
137
|
+
let atLeastOneBlockHookRegistered = false;
|
|
129
138
|
Object.entries(this.definition.modules).forEach(([key, value]) => {
|
|
130
139
|
if (Object.prototype.isPrototypeOf.call(ProvableTransactionHook, value)) {
|
|
131
140
|
this.container.register(
|
|
132
|
-
|
|
141
|
+
PROTOCOL_INJECTION_TOKENS.ProvableTransactionHook,
|
|
133
142
|
{ useToken: key },
|
|
134
143
|
{ lifecycle: Lifecycle.ContainerScoped }
|
|
135
144
|
);
|
|
136
145
|
atLeastOneTransactionHookRegistered = true;
|
|
137
146
|
}
|
|
147
|
+
if (Object.prototype.isPrototypeOf.call(ProvableBlockHook, value)) {
|
|
148
|
+
this.container.register(
|
|
149
|
+
PROTOCOL_INJECTION_TOKENS.ProvableBlockHook,
|
|
150
|
+
{ useToken: key },
|
|
151
|
+
{ lifecycle: Lifecycle.ContainerScoped }
|
|
152
|
+
);
|
|
153
|
+
atLeastOneBlockHookRegistered = true;
|
|
154
|
+
}
|
|
138
155
|
});
|
|
139
156
|
|
|
140
157
|
// We need this so that tsyringe doesn't throw when no hooks are registered
|
|
141
158
|
if (!atLeastOneTransactionHookRegistered) {
|
|
142
159
|
this.container.register(
|
|
143
|
-
|
|
160
|
+
PROTOCOL_INJECTION_TOKENS.ProvableTransactionHook,
|
|
144
161
|
{ useClass: NoopTransactionHook },
|
|
145
162
|
{ lifecycle: Lifecycle.ContainerScoped }
|
|
146
163
|
);
|
|
147
164
|
}
|
|
165
|
+
if (!atLeastOneBlockHookRegistered) {
|
|
166
|
+
this.container.register(
|
|
167
|
+
PROTOCOL_INJECTION_TOKENS.ProvableBlockHook,
|
|
168
|
+
{ useClass: NoopBlockHook },
|
|
169
|
+
{ lifecycle: Lifecycle.ContainerScoped }
|
|
170
|
+
);
|
|
171
|
+
}
|
|
148
172
|
}
|
|
149
173
|
}
|
|
150
174
|
|
|
151
175
|
export const VanillaProtocol = {
|
|
152
176
|
create() {
|
|
153
|
-
return VanillaProtocol.from(
|
|
154
|
-
{},
|
|
155
|
-
{
|
|
156
|
-
BlockProver: {},
|
|
157
|
-
StateTransitionProver: {},
|
|
158
|
-
AccountState: {},
|
|
159
|
-
}
|
|
160
|
-
);
|
|
177
|
+
return VanillaProtocol.from({});
|
|
161
178
|
},
|
|
162
179
|
|
|
163
180
|
from<AdditonalModules extends GenericProtocolModuleRecord>(
|
|
164
|
-
additionalModules: AdditonalModules
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
StateTransitionProver: typeof StateTransitionProver;
|
|
168
|
-
BlockProver: typeof BlockProver;
|
|
169
|
-
AccountState: typeof AccountStateModule;
|
|
170
|
-
}
|
|
171
|
-
>
|
|
172
|
-
): TypedClass<
|
|
173
|
-
Protocol<
|
|
174
|
-
AdditonalModules & {
|
|
175
|
-
StateTransitionProver: typeof StateTransitionProver;
|
|
176
|
-
BlockProver: typeof BlockProver;
|
|
177
|
-
AccountState: typeof AccountStateModule;
|
|
178
|
-
}
|
|
179
|
-
>
|
|
180
|
-
> {
|
|
181
|
-
return Protocol.from({
|
|
181
|
+
additionalModules: AdditonalModules
|
|
182
|
+
): TypedClass<Protocol<ProtocolModulesRecord>> {
|
|
183
|
+
return Protocol.from<ProtocolModulesRecord>({
|
|
182
184
|
modules: {
|
|
183
185
|
StateTransitionProver,
|
|
184
186
|
BlockProver,
|
|
185
187
|
AccountState: AccountStateModule,
|
|
188
|
+
BlockHeight: BlockHeightHook,
|
|
186
189
|
...additionalModules,
|
|
187
190
|
},
|
|
188
|
-
|
|
189
|
-
config,
|
|
190
191
|
});
|
|
191
192
|
},
|
|
192
193
|
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AreProofsEnabled,
|
|
3
3
|
ChildContainerProvider,
|
|
4
|
-
ConfigurableModule,
|
|
5
|
-
noop
|
|
4
|
+
ConfigurableModule, NoConfig,
|
|
5
|
+
noop
|
|
6
6
|
} from "@proto-kit/common";
|
|
7
7
|
|
|
8
8
|
import { ProtocolEnvironment } from "./ProtocolEnvironment";
|
|
9
9
|
|
|
10
10
|
export abstract class ProtocolModule<
|
|
11
|
-
Config
|
|
11
|
+
Config = NoConfig
|
|
12
12
|
> extends ConfigurableModule<Config> {
|
|
13
13
|
public protocol?: ProtocolEnvironment;
|
|
14
14
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BlockProverState } from "../prover/block/BlockProver";
|
|
2
|
+
import { NetworkState } from "../model/network/NetworkState";
|
|
3
|
+
|
|
4
|
+
import { TransitioningProtocolModule } from "./TransitioningProtocolModule";
|
|
5
|
+
|
|
6
|
+
export interface BeforeBlockParameters {
|
|
7
|
+
state: BlockProverState;
|
|
8
|
+
networkState: NetworkState;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface AfterBlockParameters {
|
|
12
|
+
state: BlockProverState;
|
|
13
|
+
networkState: NetworkState;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Purpose is to validate transition from -> to network state
|
|
17
|
+
export abstract class ProvableBlockHook<
|
|
18
|
+
Config
|
|
19
|
+
> extends TransitioningProtocolModule<Config> {
|
|
20
|
+
public abstract beforeBlock(blockData: BeforeBlockParameters): NetworkState;
|
|
21
|
+
public abstract afterBlock(blockData: AfterBlockParameters): NetworkState;
|
|
22
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { BlockProverExecutionData } from "../prover/block/BlockProvable";
|
|
2
2
|
|
|
3
3
|
import { TransitioningProtocolModule } from "./TransitioningProtocolModule";
|
|
4
|
+
import { NoConfig } from "@proto-kit/common";
|
|
4
5
|
|
|
5
|
-
export abstract class ProvableTransactionHook<
|
|
6
|
+
export abstract class ProvableTransactionHook<
|
|
7
|
+
Config = NoConfig
|
|
8
|
+
> extends TransitioningProtocolModule<Config> {
|
|
6
9
|
public abstract onTransaction(executionData: BlockProverExecutionData): void;
|
|
7
10
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ProtocolModule } from "./ProtocolModule";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* A Protocolmodule that enables it's implementing module to access to
|
|
5
|
+
* StateTransitions and state
|
|
6
|
+
*/
|
|
3
7
|
export abstract class TransitioningProtocolModule<
|
|
4
8
|
Config
|
|
5
9
|
> extends ProtocolModule<Config> {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { Field, Proof, Struct } from "o1js";
|
|
1
|
+
import { Bool, Field, Proof, Struct } from "o1js";
|
|
2
2
|
import { WithZkProgrammable } from "@proto-kit/common";
|
|
3
3
|
|
|
4
4
|
import { StateTransitionProof } from "../statetransition/StateTransitionProvable";
|
|
5
5
|
import { MethodPublicOutput } from "../../model/MethodPublicOutput";
|
|
6
6
|
import { ProtocolTransaction } from "../../model/transaction/ProtocolTransaction";
|
|
7
7
|
import { NetworkState } from "../../model/network/NetworkState";
|
|
8
|
+
import { BlockTransactionPosition } from "./BlockTransactionPosition";
|
|
8
9
|
|
|
9
10
|
export class BlockProverPublicInput extends Struct({
|
|
10
11
|
transactionsHash: Field,
|
|
@@ -15,6 +16,7 @@ export class BlockProverPublicInput extends Struct({
|
|
|
15
16
|
export class BlockProverPublicOutput extends Struct({
|
|
16
17
|
transactionsHash: Field,
|
|
17
18
|
stateRoot: Field,
|
|
19
|
+
networkStateHash: Field,
|
|
18
20
|
}) {}
|
|
19
21
|
|
|
20
22
|
export type BlockProverProof = Proof<
|
|
@@ -25,7 +27,7 @@ export type BlockProverProof = Proof<
|
|
|
25
27
|
export class BlockProverExecutionData extends Struct({
|
|
26
28
|
transaction: ProtocolTransaction,
|
|
27
29
|
networkState: NetworkState,
|
|
28
|
-
|
|
30
|
+
transactionPosition: BlockTransactionPosition,
|
|
29
31
|
}) {}
|
|
30
32
|
|
|
31
33
|
export interface BlockProvable
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/* eslint-disable max-lines */
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Bool,
|
|
4
|
+
Experimental,
|
|
5
|
+
Field,
|
|
6
|
+
type Proof,
|
|
7
|
+
Provable,
|
|
8
|
+
SelfProof,
|
|
9
|
+
Struct,
|
|
10
|
+
} from "o1js";
|
|
3
11
|
import { container, inject, injectable, injectAll } from "tsyringe";
|
|
4
12
|
import {
|
|
5
13
|
AreProofsEnabled,
|
|
@@ -29,7 +37,9 @@ import {
|
|
|
29
37
|
import { ProvableStateTransition } from "../../model/StateTransition";
|
|
30
38
|
import { ProvableTransactionHook } from "../../protocol/ProvableTransactionHook";
|
|
31
39
|
import { RuntimeMethodExecutionContext } from "../../state/context/RuntimeMethodExecutionContext";
|
|
32
|
-
import {
|
|
40
|
+
import { ProvableBlockHook } from "../../protocol/ProvableBlockHook";
|
|
41
|
+
import { NetworkState } from "../../model/network/NetworkState";
|
|
42
|
+
import { BlockTransactionPosition } from "./BlockTransactionPosition";
|
|
33
43
|
|
|
34
44
|
const errors = {
|
|
35
45
|
stateProofNotStartingAtZero: () =>
|
|
@@ -75,7 +85,8 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
75
85
|
StateTransitionProverPublicOutput
|
|
76
86
|
>,
|
|
77
87
|
public readonly runtime: ZkProgrammable<undefined, MethodPublicOutput>,
|
|
78
|
-
private readonly
|
|
88
|
+
private readonly transactionHooks: ProvableTransactionHook<unknown>[],
|
|
89
|
+
private readonly blockHooks: ProvableBlockHook<unknown>[]
|
|
79
90
|
) {
|
|
80
91
|
super();
|
|
81
92
|
}
|
|
@@ -165,17 +176,6 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
165
176
|
"Network state provided to BlockProver does not match the publicInput"
|
|
166
177
|
);
|
|
167
178
|
|
|
168
|
-
// Append tx to transaction list
|
|
169
|
-
const transactionList = new DefaultProvableHashList(
|
|
170
|
-
Field,
|
|
171
|
-
state.transactionsHash
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
const { transactionHash } = appProof.publicOutput;
|
|
175
|
-
transactionList.push(transactionHash);
|
|
176
|
-
|
|
177
|
-
stateTo.transactionsHash = transactionList.commitment;
|
|
178
|
-
|
|
179
179
|
return stateTo;
|
|
180
180
|
}
|
|
181
181
|
|
|
@@ -204,7 +204,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
204
204
|
});
|
|
205
205
|
executionContext.beforeMethod("", "", []);
|
|
206
206
|
|
|
207
|
-
this.
|
|
207
|
+
this.transactionHooks.forEach((module) => {
|
|
208
208
|
module.onTransaction(executionData);
|
|
209
209
|
});
|
|
210
210
|
|
|
@@ -234,6 +234,83 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
234
234
|
);
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
private getBeforeBlockNetworkState(
|
|
238
|
+
state: BlockProverState,
|
|
239
|
+
networkState: NetworkState
|
|
240
|
+
) {
|
|
241
|
+
return this.blockHooks.reduce<NetworkState>((networkState, blockHook) => {
|
|
242
|
+
return blockHook.beforeBlock({
|
|
243
|
+
state,
|
|
244
|
+
networkState,
|
|
245
|
+
});
|
|
246
|
+
}, networkState);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
private getAfterBlockNetworkState(
|
|
250
|
+
state: BlockProverState,
|
|
251
|
+
networkState: NetworkState
|
|
252
|
+
) {
|
|
253
|
+
return this.blockHooks.reduce<NetworkState>((networkState, blockHook) => {
|
|
254
|
+
return blockHook.afterBlock({
|
|
255
|
+
state,
|
|
256
|
+
networkState,
|
|
257
|
+
});
|
|
258
|
+
}, networkState);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private addTransactionToBundle(
|
|
262
|
+
state: BlockProverState,
|
|
263
|
+
stateTransitionProof: StateTransitionProof,
|
|
264
|
+
appProof: Proof<void, MethodPublicOutput>,
|
|
265
|
+
executionData: BlockProverExecutionData
|
|
266
|
+
): {
|
|
267
|
+
state: BlockProverState;
|
|
268
|
+
networkState: NetworkState;
|
|
269
|
+
bundleOpened: Bool;
|
|
270
|
+
bundleClosed: Bool;
|
|
271
|
+
} {
|
|
272
|
+
const { transactionPosition, networkState } = executionData;
|
|
273
|
+
const stateTo = {
|
|
274
|
+
...state,
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// Execute beforeBlook hooks and apply if it is the first tx of the bundle
|
|
278
|
+
const beforeHookResult = this.getBeforeBlockNetworkState(
|
|
279
|
+
state,
|
|
280
|
+
networkState
|
|
281
|
+
);
|
|
282
|
+
const bundleOpened = transactionPosition.equals(
|
|
283
|
+
BlockTransactionPosition.fromPositionType("FIRST")
|
|
284
|
+
);
|
|
285
|
+
const resultingNetworkState = new NetworkState(
|
|
286
|
+
Provable.if(bundleOpened, NetworkState, beforeHookResult, networkState)
|
|
287
|
+
);
|
|
288
|
+
stateTo.networkStateHash = resultingNetworkState.hash();
|
|
289
|
+
|
|
290
|
+
// TODO Modify bundle merkle tree as per specs
|
|
291
|
+
|
|
292
|
+
// Append tx to transaction list
|
|
293
|
+
const transactionList = new DefaultProvableHashList(
|
|
294
|
+
Field,
|
|
295
|
+
state.transactionsHash
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
const { transactionHash } = appProof.publicOutput;
|
|
299
|
+
transactionList.push(transactionHash);
|
|
300
|
+
|
|
301
|
+
stateTo.transactionsHash = transactionList.commitment;
|
|
302
|
+
|
|
303
|
+
return {
|
|
304
|
+
state: stateTo,
|
|
305
|
+
networkState: resultingNetworkState,
|
|
306
|
+
bundleOpened,
|
|
307
|
+
|
|
308
|
+
bundleClosed: transactionPosition.equals(
|
|
309
|
+
BlockTransactionPosition.fromPositionType("LAST")
|
|
310
|
+
),
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
237
314
|
@provableMethod()
|
|
238
315
|
public proveTransaction(
|
|
239
316
|
publicInput: BlockProverPublicInput,
|
|
@@ -247,16 +324,46 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
247
324
|
networkStateHash: publicInput.networkStateHash,
|
|
248
325
|
};
|
|
249
326
|
|
|
250
|
-
const
|
|
327
|
+
const bundleInclusionResult = this.addTransactionToBundle(
|
|
251
328
|
state,
|
|
252
329
|
stateProof,
|
|
253
330
|
appProof,
|
|
254
331
|
executionData
|
|
255
332
|
);
|
|
256
333
|
|
|
334
|
+
const stateTo = this.applyTransaction(
|
|
335
|
+
bundleInclusionResult.state,
|
|
336
|
+
stateProof,
|
|
337
|
+
appProof,
|
|
338
|
+
{
|
|
339
|
+
transaction: executionData.transaction,
|
|
340
|
+
transactionPosition: executionData.transactionPosition,
|
|
341
|
+
networkState: bundleInclusionResult.networkState,
|
|
342
|
+
}
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
// Apply afterBlock hooks
|
|
346
|
+
const afterBlockNetworkState = this.getAfterBlockNetworkState(
|
|
347
|
+
stateTo,
|
|
348
|
+
bundleInclusionResult.networkState
|
|
349
|
+
);
|
|
350
|
+
const bundleClosed = executionData.transactionPosition.equals(
|
|
351
|
+
BlockTransactionPosition.fromPositionType("LAST")
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
// We only need the hash here since this computed networkstate
|
|
355
|
+
// is only used as an input in the next bundle
|
|
356
|
+
const resultingNetworkStateHash = Provable.if(
|
|
357
|
+
bundleClosed,
|
|
358
|
+
afterBlockNetworkState.hash(),
|
|
359
|
+
stateTo.networkStateHash
|
|
360
|
+
);
|
|
361
|
+
|
|
257
362
|
return new BlockProverPublicOutput({
|
|
258
363
|
stateRoot: stateTo.stateRoot,
|
|
259
364
|
transactionsHash: stateTo.transactionsHash,
|
|
365
|
+
// eslint-disable-next-line putout/putout
|
|
366
|
+
networkStateHash: resultingNetworkStateHash,
|
|
260
367
|
});
|
|
261
368
|
}
|
|
262
369
|
|
|
@@ -294,7 +401,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
294
401
|
proof1.publicInput.networkStateHash,
|
|
295
402
|
errors.transactionsHashNotMatching("publicInput.from -> proof1.from")
|
|
296
403
|
);
|
|
297
|
-
|
|
404
|
+
proof1.publicOutput.networkStateHash.assertEquals(
|
|
298
405
|
proof2.publicInput.networkStateHash,
|
|
299
406
|
errors.transactionsHashNotMatching("proof1.to -> proof2.from")
|
|
300
407
|
);
|
|
@@ -302,6 +409,7 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
302
409
|
return new BlockProverPublicOutput({
|
|
303
410
|
stateRoot: proof2.publicOutput.stateRoot,
|
|
304
411
|
transactionsHash: proof2.publicOutput.transactionsHash,
|
|
412
|
+
networkStateHash: proof2.publicOutput.networkStateHash,
|
|
305
413
|
});
|
|
306
414
|
}
|
|
307
415
|
|
|
@@ -387,7 +495,10 @@ export class BlockProverProgrammable extends ZkProgrammable<
|
|
|
387
495
|
* then be merged to be committed to the base-layer contract
|
|
388
496
|
*/
|
|
389
497
|
@injectable()
|
|
390
|
-
export class BlockProver
|
|
498
|
+
export class BlockProver
|
|
499
|
+
extends ProtocolModule
|
|
500
|
+
implements BlockProvable
|
|
501
|
+
{
|
|
391
502
|
public zkProgrammable: BlockProverProgrammable;
|
|
392
503
|
|
|
393
504
|
public constructor(
|
|
@@ -399,15 +510,17 @@ export class BlockProver extends ProtocolModule<object> implements BlockProvable
|
|
|
399
510
|
@inject("Runtime")
|
|
400
511
|
public readonly runtime: WithZkProgrammable<undefined, MethodPublicOutput>,
|
|
401
512
|
@injectAll("ProvableTransactionHook")
|
|
402
|
-
transactionHooks: ProvableTransactionHook<unknown>[]
|
|
513
|
+
transactionHooks: ProvableTransactionHook<unknown>[],
|
|
514
|
+
@injectAll("ProvableBlockHook")
|
|
515
|
+
blockHooks: ProvableBlockHook<unknown>[]
|
|
403
516
|
) {
|
|
404
517
|
super();
|
|
405
518
|
this.zkProgrammable = new BlockProverProgrammable(
|
|
406
519
|
this,
|
|
407
520
|
stateTransitionProver.zkProgrammable,
|
|
408
521
|
runtime.zkProgrammable,
|
|
409
|
-
transactionHooks
|
|
410
|
-
|
|
522
|
+
transactionHooks,
|
|
523
|
+
blockHooks
|
|
411
524
|
);
|
|
412
525
|
}
|
|
413
526
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Bool, Field, Struct } from "o1js";
|
|
2
|
+
import { match } from "ts-pattern";
|
|
3
|
+
|
|
4
|
+
export type BlockTransactionPositionType = "FIRST" | "LAST" | "MIDDLE";
|
|
5
|
+
|
|
6
|
+
export class BlockTransactionPosition extends Struct({
|
|
7
|
+
type: Field,
|
|
8
|
+
}) {
|
|
9
|
+
private static readonly fieldMapping: Record<
|
|
10
|
+
BlockTransactionPositionType,
|
|
11
|
+
number
|
|
12
|
+
> = {
|
|
13
|
+
FIRST: 0,
|
|
14
|
+
MIDDLE: 1,
|
|
15
|
+
LAST: 2,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
public static fromPositionType(type: BlockTransactionPositionType) {
|
|
19
|
+
return new BlockTransactionPosition({
|
|
20
|
+
type: Field(BlockTransactionPosition.fieldMapping[type]).toConstant(),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public static positionTypeFromIndex(index: number, bundleLength: number) {
|
|
25
|
+
return match<number, BlockTransactionPositionType>(index)
|
|
26
|
+
.with(0, () => "FIRST")
|
|
27
|
+
.with(bundleLength - 1, () => "LAST")
|
|
28
|
+
.otherwise(() => "MIDDLE");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public equals(type: BlockTransactionPosition): Bool {
|
|
32
|
+
return this.type.equals(type.type);
|
|
33
|
+
}
|
|
34
|
+
}
|