@aztec/prover-client 0.55.1 → 0.56.0
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/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +6 -27
- package/dest/mocks/test_context.d.ts +4 -5
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +7 -9
- package/dest/orchestrator/block-building-helpers.d.ts +12 -3
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +34 -32
- package/dest/orchestrator/{proving-state.d.ts → block-proving-state.d.ts} +17 -13
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/block-proving-state.js +170 -0
- package/dest/orchestrator/epoch-proving-state.d.ts +57 -0
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/epoch-proving-state.js +151 -0
- package/dest/orchestrator/orchestrator.d.ts +32 -11
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +246 -139
- package/dest/orchestrator/tx-proving-state.d.ts +3 -2
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +54 -26
- package/dest/prover-agent/memory-proving-queue.d.ts +11 -5
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +16 -6
- package/dest/prover-agent/prover-agent.d.ts.map +1 -1
- package/dest/prover-agent/prover-agent.js +10 -10
- package/dest/prover-agent/rpc.d.ts.map +1 -1
- package/dest/prover-agent/rpc.js +6 -2
- package/dest/test/mock_prover.d.ts +4 -2
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +9 -3
- package/package.json +12 -11
- package/src/mocks/fixtures.ts +5 -49
- package/src/mocks/test_context.ts +7 -12
- package/src/orchestrator/block-building-helpers.ts +90 -57
- package/src/orchestrator/{proving-state.ts → block-proving-state.ts} +42 -40
- package/src/orchestrator/epoch-proving-state.ts +232 -0
- package/src/orchestrator/orchestrator.ts +410 -244
- package/src/orchestrator/tx-proving-state.ts +63 -27
- package/src/prover-agent/memory-proving-queue.ts +30 -16
- package/src/prover-agent/prover-agent.ts +11 -9
- package/src/prover-agent/rpc.ts +6 -0
- package/src/test/mock_prover.ts +23 -1
- package/dest/orchestrator/proving-state.d.ts.map +0 -1
- package/dest/orchestrator/proving-state.js +0 -170
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/prover-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.56.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
7
7
|
"./prover-agent": "./dest/prover-agent/index.js",
|
|
8
|
-
"./orchestrator": "./dest/orchestrator/index.js"
|
|
8
|
+
"./orchestrator": "./dest/orchestrator/index.js",
|
|
9
|
+
"./helpers": "./dest/orchestrator/block-building-helpers.js"
|
|
9
10
|
},
|
|
10
11
|
"typedocOptions": {
|
|
11
12
|
"entryPoints": [
|
|
@@ -59,15 +60,15 @@
|
|
|
59
60
|
]
|
|
60
61
|
},
|
|
61
62
|
"dependencies": {
|
|
62
|
-
"@aztec/bb-prover": "0.
|
|
63
|
-
"@aztec/circuit-types": "0.
|
|
64
|
-
"@aztec/circuits.js": "0.
|
|
65
|
-
"@aztec/foundation": "0.
|
|
66
|
-
"@aztec/kv-store": "0.
|
|
67
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
68
|
-
"@aztec/simulator": "0.
|
|
69
|
-
"@aztec/telemetry-client": "0.
|
|
70
|
-
"@aztec/world-state": "0.
|
|
63
|
+
"@aztec/bb-prover": "0.56.0",
|
|
64
|
+
"@aztec/circuit-types": "0.56.0",
|
|
65
|
+
"@aztec/circuits.js": "0.56.0",
|
|
66
|
+
"@aztec/foundation": "0.56.0",
|
|
67
|
+
"@aztec/kv-store": "0.56.0",
|
|
68
|
+
"@aztec/noir-protocol-circuits-types": "0.56.0",
|
|
69
|
+
"@aztec/simulator": "0.56.0",
|
|
70
|
+
"@aztec/telemetry-client": "0.56.0",
|
|
71
|
+
"@aztec/world-state": "0.56.0",
|
|
71
72
|
"@noir-lang/types": "portal:../../noir/packages/types",
|
|
72
73
|
"commander": "^12.1.0",
|
|
73
74
|
"lodash.chunk": "^4.2.0",
|
package/src/mocks/fixtures.ts
CHANGED
|
@@ -2,29 +2,20 @@ import {
|
|
|
2
2
|
MerkleTreeId,
|
|
3
3
|
type ProcessedTx,
|
|
4
4
|
makeEmptyProcessedTx as makeEmptyProcessedTxFromHistoricalTreeRoots,
|
|
5
|
-
makeProcessedTx,
|
|
6
|
-
mockTx,
|
|
7
5
|
} from '@aztec/circuit-types';
|
|
6
|
+
import { makeBloatedProcessedTx as makeBloatedProcessedTxWithVKRoot } from '@aztec/circuit-types/test';
|
|
8
7
|
import {
|
|
9
8
|
AztecAddress,
|
|
10
9
|
EthAddress,
|
|
11
10
|
Fr,
|
|
12
11
|
GasFees,
|
|
13
12
|
GlobalVariables,
|
|
14
|
-
KernelCircuitPublicInputs,
|
|
15
|
-
LogHash,
|
|
16
|
-
MAX_L2_TO_L1_MSGS_PER_TX,
|
|
17
13
|
MAX_NOTE_HASHES_PER_TX,
|
|
18
14
|
MAX_NULLIFIERS_PER_TX,
|
|
19
|
-
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
20
15
|
NULLIFIER_TREE_HEIGHT,
|
|
21
16
|
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
22
17
|
PublicDataTreeLeaf,
|
|
23
|
-
PublicDataUpdateRequest,
|
|
24
|
-
ScopedLogHash,
|
|
25
18
|
} from '@aztec/circuits.js';
|
|
26
|
-
import { fr, makeScopedL2ToL1Message } from '@aztec/circuits.js/testing';
|
|
27
|
-
import { makeTuple } from '@aztec/foundation/array';
|
|
28
19
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
29
20
|
import { randomBytes } from '@aztec/foundation/crypto';
|
|
30
21
|
import { type DebugLogger } from '@aztec/foundation/log';
|
|
@@ -98,43 +89,8 @@ export async function getSimulationProvider(
|
|
|
98
89
|
return new WASMSimulator();
|
|
99
90
|
}
|
|
100
91
|
|
|
101
|
-
export const makeBloatedProcessedTx = (builderDb: MerkleTreeOperations, seed = 0x1) =>
|
|
102
|
-
|
|
103
|
-
const tx = mockTx(seed);
|
|
104
|
-
const kernelOutput = KernelCircuitPublicInputs.empty();
|
|
105
|
-
kernelOutput.constants.vkTreeRoot = getVKTreeRoot();
|
|
106
|
-
kernelOutput.constants.historicalHeader = builderDb.getInitialHeader();
|
|
107
|
-
kernelOutput.end.publicDataUpdateRequests = makeTuple(
|
|
108
|
-
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
109
|
-
i => new PublicDataUpdateRequest(fr(i), fr(i + 10), i + 20),
|
|
110
|
-
seed + 0x500,
|
|
111
|
-
);
|
|
112
|
-
kernelOutput.end.publicDataUpdateRequests = makeTuple(
|
|
113
|
-
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
114
|
-
i => new PublicDataUpdateRequest(fr(i), fr(i + 10), i + 20),
|
|
115
|
-
seed + 0x600,
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
const processedTx = makeProcessedTx(tx, kernelOutput, []);
|
|
119
|
-
|
|
120
|
-
processedTx.data.end.noteHashes = makeTuple(MAX_NOTE_HASHES_PER_TX, fr, seed + 0x100);
|
|
121
|
-
processedTx.data.end.nullifiers = makeTuple(MAX_NULLIFIERS_PER_TX, fr, seed + 0x100000);
|
|
122
|
-
|
|
123
|
-
processedTx.data.end.nullifiers[tx.data.forPublic!.end.nullifiers.length - 1] = Fr.zero();
|
|
124
|
-
|
|
125
|
-
processedTx.data.end.l2ToL1Msgs = makeTuple(MAX_L2_TO_L1_MSGS_PER_TX, makeScopedL2ToL1Message, seed + 0x300);
|
|
126
|
-
processedTx.noteEncryptedLogs.unrollLogs().forEach((log, i) => {
|
|
127
|
-
processedTx.data.end.noteEncryptedLogsHashes[i] = new LogHash(Fr.fromBuffer(log.hash()), 0, new Fr(log.length));
|
|
128
|
-
});
|
|
129
|
-
processedTx.encryptedLogs.unrollLogs().forEach((log, i) => {
|
|
130
|
-
processedTx.data.end.encryptedLogsHashes[i] = new ScopedLogHash(
|
|
131
|
-
new LogHash(Fr.fromBuffer(log.hash()), 0, new Fr(log.length)),
|
|
132
|
-
log.maskedContractAddress,
|
|
133
|
-
);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
return processedTx;
|
|
137
|
-
};
|
|
92
|
+
export const makeBloatedProcessedTx = (builderDb: MerkleTreeOperations, seed = 0x1) =>
|
|
93
|
+
makeBloatedProcessedTxWithVKRoot(builderDb, getVKTreeRoot(), seed);
|
|
138
94
|
|
|
139
95
|
export const makeEmptyProcessedTx = (builderDb: MerkleTreeOperations, chainId: Fr, version: Fr) => {
|
|
140
96
|
const header = builderDb.getInitialHeader();
|
|
@@ -179,9 +135,9 @@ export const makeGlobals = (blockNumber: number) => {
|
|
|
179
135
|
return new GlobalVariables(
|
|
180
136
|
Fr.ZERO,
|
|
181
137
|
Fr.ZERO,
|
|
182
|
-
new Fr(blockNumber)
|
|
138
|
+
new Fr(blockNumber) /** block number */,
|
|
183
139
|
new Fr(blockNumber) /** slot number */,
|
|
184
|
-
Fr
|
|
140
|
+
new Fr(blockNumber) /** timestamp */,
|
|
185
141
|
EthAddress.ZERO,
|
|
186
142
|
AztecAddress.ZERO,
|
|
187
143
|
GasFees.empty(),
|
|
@@ -13,7 +13,6 @@ import { type Fr } from '@aztec/foundation/fields';
|
|
|
13
13
|
import { type DebugLogger } from '@aztec/foundation/log';
|
|
14
14
|
import { openTmpStore } from '@aztec/kv-store/utils';
|
|
15
15
|
import {
|
|
16
|
-
type ContractsDataSourcePublicDB,
|
|
17
16
|
type PublicExecutionResult,
|
|
18
17
|
PublicExecutionResultBuilder,
|
|
19
18
|
type PublicExecutor,
|
|
@@ -21,7 +20,7 @@ import {
|
|
|
21
20
|
RealPublicKernelCircuitSimulator,
|
|
22
21
|
type SimulationProvider,
|
|
23
22
|
WASMSimulator,
|
|
24
|
-
type
|
|
23
|
+
type WorldStateDB,
|
|
25
24
|
} from '@aztec/simulator';
|
|
26
25
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
27
26
|
import { MerkleTrees } from '@aztec/world-state';
|
|
@@ -33,7 +32,7 @@ import { tmpdir } from 'os';
|
|
|
33
32
|
import { join } from 'path';
|
|
34
33
|
|
|
35
34
|
import { TestCircuitProver } from '../../../bb-prover/src/test/test_circuit_prover.js';
|
|
36
|
-
import { ProvingOrchestrator } from '../orchestrator/
|
|
35
|
+
import { ProvingOrchestrator } from '../orchestrator/index.js';
|
|
37
36
|
import { MemoryProvingQueue } from '../prover-agent/memory-proving-queue.js';
|
|
38
37
|
import { ProverAgent } from '../prover-agent/prover-agent.js';
|
|
39
38
|
import { getEnvironmentConfig, getSimulationProvider, makeGlobals } from './fixtures.js';
|
|
@@ -41,8 +40,7 @@ import { getEnvironmentConfig, getSimulationProvider, makeGlobals } from './fixt
|
|
|
41
40
|
export class TestContext {
|
|
42
41
|
constructor(
|
|
43
42
|
public publicExecutor: MockProxy<PublicExecutor>,
|
|
44
|
-
public
|
|
45
|
-
public publicWorldStateDB: MockProxy<WorldStatePublicDB>,
|
|
43
|
+
public worldStateDB: MockProxy<WorldStateDB>,
|
|
46
44
|
public publicProcessor: PublicProcessor,
|
|
47
45
|
public simulationProvider: SimulationProvider,
|
|
48
46
|
public globalVariables: GlobalVariables,
|
|
@@ -71,8 +69,7 @@ export class TestContext {
|
|
|
71
69
|
const globalVariables = makeGlobals(blockNumber);
|
|
72
70
|
|
|
73
71
|
const publicExecutor = mock<PublicExecutor>();
|
|
74
|
-
const
|
|
75
|
-
const publicWorldStateDB = mock<WorldStatePublicDB>();
|
|
72
|
+
const worldStateDB = mock<WorldStateDB>();
|
|
76
73
|
const publicKernel = new RealPublicKernelCircuitSimulator(new WASMSimulator());
|
|
77
74
|
const telemetry = new NoopTelemetryClient();
|
|
78
75
|
|
|
@@ -88,14 +85,13 @@ export class TestContext {
|
|
|
88
85
|
actualDb = ws.asLatest();
|
|
89
86
|
}
|
|
90
87
|
|
|
91
|
-
const processor =
|
|
88
|
+
const processor = PublicProcessor.create(
|
|
92
89
|
actualDb,
|
|
93
90
|
publicExecutor,
|
|
94
91
|
publicKernel,
|
|
95
92
|
GlobalVariables.empty(),
|
|
96
93
|
Header.empty(),
|
|
97
|
-
|
|
98
|
-
publicWorldStateDB,
|
|
94
|
+
worldStateDB,
|
|
99
95
|
telemetry,
|
|
100
96
|
);
|
|
101
97
|
|
|
@@ -130,8 +126,7 @@ export class TestContext {
|
|
|
130
126
|
|
|
131
127
|
return new this(
|
|
132
128
|
publicExecutor,
|
|
133
|
-
|
|
134
|
-
publicWorldStateDB,
|
|
129
|
+
worldStateDB,
|
|
135
130
|
processor,
|
|
136
131
|
simulationProvider,
|
|
137
132
|
globalVariables,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MerkleTreeId, type ProcessedTx } from '@aztec/circuit-types';
|
|
1
|
+
import { type Body, MerkleTreeId, type ProcessedTx, TxEffect, getTreeHeight } from '@aztec/circuit-types';
|
|
2
2
|
import {
|
|
3
3
|
ARCHIVE_HEIGHT,
|
|
4
4
|
AppendOnlyTreeSnapshot,
|
|
@@ -6,28 +6,29 @@ import {
|
|
|
6
6
|
BaseRollupInputs,
|
|
7
7
|
BlockMergeRollupInputs,
|
|
8
8
|
type BlockRootOrBlockMergePublicInputs,
|
|
9
|
-
BlockRootRollupInputs,
|
|
10
9
|
ConstantRollupData,
|
|
10
|
+
ContentCommitment,
|
|
11
11
|
Fr,
|
|
12
12
|
type GlobalVariables,
|
|
13
|
-
|
|
13
|
+
Header,
|
|
14
14
|
KernelData,
|
|
15
|
-
type L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
|
|
16
15
|
MAX_NULLIFIERS_PER_TX,
|
|
17
16
|
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
18
17
|
MembershipWitness,
|
|
19
18
|
MergeRollupInputs,
|
|
19
|
+
MerkleTreeCalculator,
|
|
20
20
|
type NESTED_RECURSIVE_PROOF_LENGTH,
|
|
21
21
|
NOTE_HASH_SUBTREE_HEIGHT,
|
|
22
22
|
NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH,
|
|
23
23
|
NULLIFIER_SUBTREE_HEIGHT,
|
|
24
24
|
NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH,
|
|
25
25
|
NULLIFIER_TREE_HEIGHT,
|
|
26
|
-
|
|
26
|
+
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
27
27
|
NullifierLeafPreimage,
|
|
28
28
|
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
29
29
|
PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH,
|
|
30
30
|
PUBLIC_DATA_TREE_HEIGHT,
|
|
31
|
+
type ParityPublicInputs,
|
|
31
32
|
PartialStateReference,
|
|
32
33
|
PreviousRollupBlockData,
|
|
33
34
|
PreviousRollupData,
|
|
@@ -37,21 +38,25 @@ import {
|
|
|
37
38
|
PublicDataUpdateRequest,
|
|
38
39
|
type RECURSIVE_PROOF_LENGTH,
|
|
39
40
|
type RecursiveProof,
|
|
40
|
-
type RootParityInput,
|
|
41
41
|
RootRollupInputs,
|
|
42
42
|
StateDiffHints,
|
|
43
|
-
|
|
43
|
+
StateReference,
|
|
44
44
|
VK_TREE_HEIGHT,
|
|
45
45
|
type VerificationKeyAsFields,
|
|
46
46
|
type VerificationKeyData,
|
|
47
47
|
} from '@aztec/circuits.js';
|
|
48
48
|
import { assertPermutation, makeTuple } from '@aztec/foundation/array';
|
|
49
49
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
50
|
+
import { sha256Trunc } from '@aztec/foundation/crypto';
|
|
51
|
+
import { type DebugLogger } from '@aztec/foundation/log';
|
|
50
52
|
import { type Tuple, assertLength, toFriendlyJSON } from '@aztec/foundation/serialize';
|
|
53
|
+
import { computeUnbalancedMerkleRoot } from '@aztec/foundation/trees';
|
|
51
54
|
import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types';
|
|
52
55
|
import { HintsBuilder, computeFeePayerBalanceLeafSlot } from '@aztec/simulator';
|
|
53
56
|
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
54
57
|
|
|
58
|
+
import { inspect } from 'util';
|
|
59
|
+
|
|
55
60
|
/**
|
|
56
61
|
* Type representing the names of the trees for the base rollup.
|
|
57
62
|
*/
|
|
@@ -189,7 +194,6 @@ export function createMergeRollupInputs(
|
|
|
189
194
|
return mergeInputs;
|
|
190
195
|
}
|
|
191
196
|
|
|
192
|
-
// TODO(#7346): Integrate batch rollup circuits and test below
|
|
193
197
|
export function createBlockMergeRollupInputs(
|
|
194
198
|
left: [
|
|
195
199
|
BlockRootOrBlockMergePublicInputs,
|
|
@@ -209,6 +213,80 @@ export function createBlockMergeRollupInputs(
|
|
|
209
213
|
return mergeInputs;
|
|
210
214
|
}
|
|
211
215
|
|
|
216
|
+
export function buildHeaderFromCircuitOutputs(
|
|
217
|
+
previousMergeData: [BaseOrMergeRollupPublicInputs, BaseOrMergeRollupPublicInputs],
|
|
218
|
+
parityPublicInputs: ParityPublicInputs,
|
|
219
|
+
rootRollupOutputs: BlockRootOrBlockMergePublicInputs,
|
|
220
|
+
updatedL1ToL2TreeSnapshot: AppendOnlyTreeSnapshot,
|
|
221
|
+
logger?: DebugLogger,
|
|
222
|
+
) {
|
|
223
|
+
const contentCommitment = new ContentCommitment(
|
|
224
|
+
new Fr(previousMergeData[0].numTxs + previousMergeData[1].numTxs),
|
|
225
|
+
sha256Trunc(
|
|
226
|
+
Buffer.concat([previousMergeData[0].txsEffectsHash.toBuffer(), previousMergeData[1].txsEffectsHash.toBuffer()]),
|
|
227
|
+
),
|
|
228
|
+
parityPublicInputs.shaRoot.toBuffer(),
|
|
229
|
+
sha256Trunc(Buffer.concat([previousMergeData[0].outHash.toBuffer(), previousMergeData[1].outHash.toBuffer()])),
|
|
230
|
+
);
|
|
231
|
+
const state = new StateReference(updatedL1ToL2TreeSnapshot, previousMergeData[1].end);
|
|
232
|
+
const header = new Header(
|
|
233
|
+
rootRollupOutputs.previousArchive,
|
|
234
|
+
contentCommitment,
|
|
235
|
+
state,
|
|
236
|
+
previousMergeData[0].constants.globalVariables,
|
|
237
|
+
previousMergeData[0].accumulatedFees.add(previousMergeData[1].accumulatedFees),
|
|
238
|
+
);
|
|
239
|
+
if (!header.hash().equals(rootRollupOutputs.endBlockHash)) {
|
|
240
|
+
logger?.error(
|
|
241
|
+
`Block header mismatch when building header from circuit outputs.` +
|
|
242
|
+
`\n\nHeader: ${inspect(header)}` +
|
|
243
|
+
`\n\nCircuit: ${toFriendlyJSON(rootRollupOutputs)}`,
|
|
244
|
+
);
|
|
245
|
+
throw new Error(`Block header mismatch when building from circuit outputs`);
|
|
246
|
+
}
|
|
247
|
+
return header;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export async function buildHeaderFromTxEffects(
|
|
251
|
+
body: Body,
|
|
252
|
+
globalVariables: GlobalVariables,
|
|
253
|
+
l1ToL2Messages: Fr[],
|
|
254
|
+
db: MerkleTreeOperations,
|
|
255
|
+
) {
|
|
256
|
+
const stateReference = new StateReference(
|
|
257
|
+
await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db),
|
|
258
|
+
new PartialStateReference(
|
|
259
|
+
await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
|
|
260
|
+
await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
|
|
261
|
+
await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
|
|
262
|
+
),
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const previousArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
266
|
+
|
|
267
|
+
const outHash = computeUnbalancedMerkleRoot(
|
|
268
|
+
body.txEffects.map(tx => tx.txOutHash()),
|
|
269
|
+
TxEffect.empty().txOutHash(),
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
l1ToL2Messages = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
273
|
+
const hasher = (left: Buffer, right: Buffer) => sha256Trunc(Buffer.concat([left, right]));
|
|
274
|
+
const parityHeight = Math.ceil(Math.log2(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP));
|
|
275
|
+
const parityShaRoot = new MerkleTreeCalculator(parityHeight, Fr.ZERO.toBuffer(), hasher).computeTreeRoot(
|
|
276
|
+
l1ToL2Messages.map(msg => msg.toBuffer()),
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
const contentCommitment = new ContentCommitment(
|
|
280
|
+
new Fr(body.numberOfTxsIncludingPadded),
|
|
281
|
+
body.getTxsEffectsHash(),
|
|
282
|
+
parityShaRoot,
|
|
283
|
+
outHash,
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const fees = body.txEffects.reduce((acc, tx) => acc.add(tx.transactionFee), Fr.ZERO);
|
|
287
|
+
return new Header(previousArchive, contentCommitment, stateReference, globalVariables, fees);
|
|
288
|
+
}
|
|
289
|
+
|
|
212
290
|
// Validate that the roots of all local trees match the output of the root circuit simulation
|
|
213
291
|
export async function validateBlockRootOutput(
|
|
214
292
|
blockRootOutput: BlockRootOrBlockMergePublicInputs,
|
|
@@ -238,58 +316,13 @@ export async function validateState(state: StateReference, db: MerkleTreeOperati
|
|
|
238
316
|
);
|
|
239
317
|
}
|
|
240
318
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
verificationKeyLeft: VerificationKeyAsFields,
|
|
246
|
-
rollupOutputRight: BaseOrMergeRollupPublicInputs,
|
|
247
|
-
rollupProofRight: RecursiveProof<typeof NESTED_RECURSIVE_PROOF_LENGTH>,
|
|
248
|
-
verificationKeyRight: VerificationKeyAsFields,
|
|
249
|
-
l1ToL2Roots: RootParityInput<typeof NESTED_RECURSIVE_PROOF_LENGTH>,
|
|
250
|
-
newL1ToL2Messages: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>,
|
|
251
|
-
messageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
252
|
-
messageTreeRootSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>,
|
|
253
|
-
db: MerkleTreeOperations,
|
|
254
|
-
proverId: Fr,
|
|
255
|
-
) {
|
|
256
|
-
const previousRollupData: BlockRootRollupInputs['previousRollupData'] = [
|
|
257
|
-
getPreviousRollupDataFromPublicInputs(rollupOutputLeft, rollupProofLeft, verificationKeyLeft),
|
|
258
|
-
getPreviousRollupDataFromPublicInputs(rollupOutputRight, rollupProofRight, verificationKeyRight),
|
|
259
|
-
];
|
|
260
|
-
|
|
261
|
-
const getRootTreeSiblingPath = async (treeId: MerkleTreeId) => {
|
|
262
|
-
const { size } = await db.getTreeInfo(treeId);
|
|
263
|
-
const path = await db.getSiblingPath(treeId, size);
|
|
264
|
-
return path.toFields();
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
// Get blocks tree
|
|
268
|
-
const startArchiveSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
269
|
-
const newArchiveSiblingPathArray = await getRootTreeSiblingPath(MerkleTreeId.ARCHIVE);
|
|
270
|
-
|
|
271
|
-
const newArchiveSiblingPath = makeTuple(
|
|
272
|
-
ARCHIVE_HEIGHT,
|
|
273
|
-
i => (i < newArchiveSiblingPathArray.length ? newArchiveSiblingPathArray[i] : Fr.ZERO),
|
|
274
|
-
0,
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
return BlockRootRollupInputs.from({
|
|
278
|
-
previousRollupData,
|
|
279
|
-
l1ToL2Roots,
|
|
280
|
-
newL1ToL2Messages,
|
|
281
|
-
newL1ToL2MessageTreeRootSiblingPath: messageTreeRootSiblingPath,
|
|
282
|
-
startL1ToL2MessageTreeSnapshot: messageTreeSnapshot,
|
|
283
|
-
startArchiveSnapshot,
|
|
284
|
-
newArchiveSiblingPath,
|
|
285
|
-
// TODO(#7346): Inject previous block hash (required when integrating batch rollup circuits)
|
|
286
|
-
previousBlockHash: Fr.ZERO,
|
|
287
|
-
proverId,
|
|
288
|
-
});
|
|
319
|
+
export async function getRootTreeSiblingPath<TID extends MerkleTreeId>(treeId: TID, db: MerkleTreeOperations) {
|
|
320
|
+
const { size } = await db.getTreeInfo(treeId);
|
|
321
|
+
const path = await db.getSiblingPath(treeId, size);
|
|
322
|
+
return padArrayEnd(path.toFields(), Fr.ZERO, getTreeHeight(treeId));
|
|
289
323
|
}
|
|
290
324
|
|
|
291
325
|
// Builds the inputs for the final root rollup circuit, without making any changes to trees
|
|
292
|
-
// TODO(#7346): Integrate batch rollup circuits and test below
|
|
293
326
|
export function getRootRollupInput(
|
|
294
327
|
rollupOutputLeft: BlockRootOrBlockMergePublicInputs,
|
|
295
328
|
rollupProofLeft: RecursiveProof<typeof NESTED_RECURSIVE_PROOF_LENGTH>,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type L2Block, type MerkleTreeId, type ProvingResult } from '@aztec/circuit-types';
|
|
2
2
|
import {
|
|
3
|
+
type ARCHIVE_HEIGHT,
|
|
3
4
|
type AppendOnlyTreeSnapshot,
|
|
4
5
|
type BaseOrMergeRollupPublicInputs,
|
|
5
6
|
type BlockRootOrBlockMergePublicInputs,
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
type L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
|
|
9
10
|
type NESTED_RECURSIVE_PROOF_LENGTH,
|
|
10
11
|
type NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
12
|
+
NUM_BASE_PARITY_PER_ROOT_PARITY,
|
|
11
13
|
type Proof,
|
|
12
14
|
type RECURSIVE_PROOF_LENGTH,
|
|
13
15
|
type RecursiveProof,
|
|
@@ -18,6 +20,12 @@ import { type Tuple } from '@aztec/foundation/serialize';
|
|
|
18
20
|
|
|
19
21
|
import { type TxProvingState } from './tx-proving-state.js';
|
|
20
22
|
|
|
23
|
+
enum PROVING_STATE_LIFECYCLE {
|
|
24
|
+
PROVING_STATE_CREATED,
|
|
25
|
+
PROVING_STATE_RESOLVED,
|
|
26
|
+
PROVING_STATE_REJECTED,
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
export type MergeRollupInputData = {
|
|
22
30
|
inputs: [BaseOrMergeRollupPublicInputs | undefined, BaseOrMergeRollupPublicInputs | undefined];
|
|
23
31
|
proofs: [
|
|
@@ -29,20 +37,11 @@ export type MergeRollupInputData = {
|
|
|
29
37
|
|
|
30
38
|
export type TreeSnapshots = Map<MerkleTreeId, AppendOnlyTreeSnapshot>;
|
|
31
39
|
|
|
32
|
-
enum PROVING_STATE_LIFECYCLE {
|
|
33
|
-
PROVING_STATE_CREATED,
|
|
34
|
-
PROVING_STATE_FULL,
|
|
35
|
-
PROVING_STATE_RESOLVED,
|
|
36
|
-
PROVING_STATE_REJECTED,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
40
|
/**
|
|
40
|
-
* The current state of the proving schedule
|
|
41
|
-
*
|
|
42
|
-
* Captures resolve and reject callbacks to provide a promise base interface to the consumer of our proving.
|
|
41
|
+
* The current state of the proving schedule for a given block. Managed by ProvingState.
|
|
42
|
+
* Contains the raw inputs and intermediate state to generate every constituent proof in the tree.
|
|
43
43
|
*/
|
|
44
|
-
export class
|
|
45
|
-
private provingStateLifecycle = PROVING_STATE_LIFECYCLE.PROVING_STATE_CREATED;
|
|
44
|
+
export class BlockProvingState {
|
|
46
45
|
private mergeRollupInputs: MergeRollupInputData[] = [];
|
|
47
46
|
private rootParityInputs: Array<RootParityInput<typeof RECURSIVE_PROOF_LENGTH> | undefined> = [];
|
|
48
47
|
private finalRootParityInputs: RootParityInput<typeof NESTED_RECURSIVE_PROOF_LENGTH> | undefined;
|
|
@@ -50,17 +49,28 @@ export class ProvingState {
|
|
|
50
49
|
public finalProof: Proof | undefined;
|
|
51
50
|
public block: L2Block | undefined;
|
|
52
51
|
private txs: TxProvingState[] = [];
|
|
52
|
+
|
|
53
|
+
private provingStateLifecycle = PROVING_STATE_LIFECYCLE.PROVING_STATE_CREATED;
|
|
54
|
+
|
|
53
55
|
constructor(
|
|
56
|
+
public readonly index: number,
|
|
54
57
|
public readonly totalNumTxs: number,
|
|
55
|
-
private completionCallback: (result: ProvingResult) => void,
|
|
56
|
-
private rejectionCallback: (reason: string) => void,
|
|
57
58
|
public readonly globalVariables: GlobalVariables,
|
|
58
59
|
public readonly newL1ToL2Messages: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>,
|
|
59
|
-
numRootParityInputs: number,
|
|
60
60
|
public readonly messageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
61
61
|
public readonly messageTreeRootSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>,
|
|
62
|
+
public readonly messageTreeSnapshotAfterInsertion: AppendOnlyTreeSnapshot,
|
|
63
|
+
public readonly archiveTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
64
|
+
public readonly archiveTreeRootSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>,
|
|
65
|
+
public readonly previousBlockHash: Fr,
|
|
66
|
+
private completionCallback?: (result: ProvingResult) => void,
|
|
67
|
+
private rejectionCallback?: (reason: string) => void,
|
|
62
68
|
) {
|
|
63
|
-
this.rootParityInputs = Array.from({ length:
|
|
69
|
+
this.rootParityInputs = Array.from({ length: NUM_BASE_PARITY_PER_ROOT_PARITY }).map(_ => undefined);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public get blockNumber() {
|
|
73
|
+
return this.globalVariables.blockNumber.toNumber();
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
// Returns the number of levels of merge rollups
|
|
@@ -95,12 +105,8 @@ export class ProvingState {
|
|
|
95
105
|
}
|
|
96
106
|
|
|
97
107
|
// Adds a transaction to the proving state, returns it's index
|
|
98
|
-
// Will update the proving life cycle if this is the last transaction
|
|
99
108
|
public addNewTx(tx: TxProvingState) {
|
|
100
109
|
this.txs.push(tx);
|
|
101
|
-
if (this.txs.length === this.totalNumTxs) {
|
|
102
|
-
this.provingStateLifecycle = PROVING_STATE_LIFECYCLE.PROVING_STATE_FULL;
|
|
103
|
-
}
|
|
104
110
|
return this.txs.length - 1;
|
|
105
111
|
}
|
|
106
112
|
|
|
@@ -124,19 +130,6 @@ export class ProvingState {
|
|
|
124
130
|
return this.rootParityInputs;
|
|
125
131
|
}
|
|
126
132
|
|
|
127
|
-
// Returns true if this proving state is still valid, false otherwise
|
|
128
|
-
public verifyState() {
|
|
129
|
-
return (
|
|
130
|
-
this.provingStateLifecycle === PROVING_STATE_LIFECYCLE.PROVING_STATE_CREATED ||
|
|
131
|
-
this.provingStateLifecycle === PROVING_STATE_LIFECYCLE.PROVING_STATE_FULL
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Returns true if we are still able to accept transactions, false otherwise
|
|
136
|
-
public isAcceptingTransactions() {
|
|
137
|
-
return this.provingStateLifecycle === PROVING_STATE_LIFECYCLE.PROVING_STATE_CREATED;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
133
|
// Returns the complete set of transaction proving state objects
|
|
141
134
|
public get allTxs() {
|
|
142
135
|
return this.txs;
|
|
@@ -211,28 +204,37 @@ export class ProvingState {
|
|
|
211
204
|
return this.rootParityInputs.findIndex(p => !p) === -1;
|
|
212
205
|
}
|
|
213
206
|
|
|
214
|
-
//
|
|
215
|
-
public
|
|
216
|
-
|
|
207
|
+
// Returns true if we are still able to accept transactions, false otherwise
|
|
208
|
+
public isAcceptingTransactions() {
|
|
209
|
+
return (
|
|
210
|
+
this.provingStateLifecycle === PROVING_STATE_LIFECYCLE.PROVING_STATE_CREATED && this.totalNumTxs > this.txs.length
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Returns true if this proving state is still valid, false otherwise
|
|
215
|
+
public verifyState() {
|
|
216
|
+
return this.provingStateLifecycle === PROVING_STATE_LIFECYCLE.PROVING_STATE_CREATED;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
// Attempts to reject the proving state promise with the given reason
|
|
220
|
-
// Does nothing if not in a valid state
|
|
221
220
|
public reject(reason: string) {
|
|
222
221
|
if (!this.verifyState()) {
|
|
223
222
|
return;
|
|
224
223
|
}
|
|
225
224
|
this.provingStateLifecycle = PROVING_STATE_LIFECYCLE.PROVING_STATE_REJECTED;
|
|
226
|
-
this.rejectionCallback
|
|
225
|
+
if (this.rejectionCallback) {
|
|
226
|
+
this.rejectionCallback(reason);
|
|
227
|
+
}
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
// Attempts to resolve the proving state promise with the given result
|
|
230
|
-
// Does nothing if not in a valid state
|
|
231
231
|
public resolve(result: ProvingResult) {
|
|
232
232
|
if (!this.verifyState()) {
|
|
233
233
|
return;
|
|
234
234
|
}
|
|
235
235
|
this.provingStateLifecycle = PROVING_STATE_LIFECYCLE.PROVING_STATE_RESOLVED;
|
|
236
|
-
this.completionCallback
|
|
236
|
+
if (this.completionCallback) {
|
|
237
|
+
this.completionCallback(result);
|
|
238
|
+
}
|
|
237
239
|
}
|
|
238
240
|
}
|