@aztec/prover-client 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2 → 0.75.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/bin/get-proof-inputs.d.ts +2 -0
- package/dest/bin/get-proof-inputs.d.ts.map +1 -0
- package/dest/bin/get-proof-inputs.js +16 -18
- package/dest/block_builder/index.d.ts +6 -0
- package/dest/block_builder/index.d.ts.map +1 -0
- package/dest/block_builder/index.js +1 -0
- package/dest/block_builder/light.d.ts +31 -0
- package/dest/block_builder/light.d.ts.map +1 -0
- package/dest/block_builder/light.js +13 -23
- package/dest/config.d.ts +17 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +11 -9
- package/dest/index.d.ts +4 -0
- package/dest/index.d.ts.map +1 -0
- package/dest/index.js +1 -0
- package/dest/mocks/fixtures.d.ts +19 -0
- package/dest/mocks/fixtures.d.ts.map +1 -0
- package/dest/mocks/fixtures.js +26 -28
- package/dest/mocks/test_context.d.ts +49 -0
- package/dest/mocks/test_context.d.ts.map +1 -0
- package/dest/mocks/test_context.js +31 -55
- package/dest/orchestrator/block-building-helpers.d.ts +50 -0
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -0
- package/dest/orchestrator/block-building-helpers.js +90 -90
- package/dest/orchestrator/block-proving-state.d.ts +71 -0
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/block-proving-state.js +70 -95
- package/dest/orchestrator/epoch-proving-state.d.ts +56 -0
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/epoch-proving-state.js +40 -53
- package/dest/orchestrator/index.d.ts +2 -0
- package/dest/orchestrator/index.d.ts.map +1 -0
- package/dest/orchestrator/index.js +1 -0
- package/dest/orchestrator/orchestrator.d.ts +108 -0
- package/dest/orchestrator/orchestrator.d.ts.map +1 -0
- package/dest/orchestrator/orchestrator.js +653 -649
- package/dest/orchestrator/orchestrator_metrics.d.ts +8 -0
- package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -0
- package/dest/orchestrator/orchestrator_metrics.js +3 -4
- package/dest/orchestrator/tx-proving-state.d.ts +31 -0
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/tx-proving-state.js +51 -52
- package/dest/prover-agent/index.d.ts +4 -0
- package/dest/prover-agent/index.d.ts.map +1 -0
- package/dest/prover-agent/index.js +1 -0
- package/dest/prover-agent/memory-proving-queue.d.ts +82 -0
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -0
- package/dest/prover-agent/memory-proving-queue.js +248 -237
- package/dest/prover-agent/prover-agent.d.ts +43 -0
- package/dest/prover-agent/prover-agent.d.ts.map +1 -0
- package/dest/prover-agent/prover-agent.js +187 -184
- package/dest/prover-agent/proving-error.d.ts +5 -0
- package/dest/prover-agent/proving-error.d.ts.map +1 -0
- package/dest/prover-agent/proving-error.js +1 -0
- package/dest/prover-agent/queue_metrics.d.ts +10 -0
- package/dest/prover-agent/queue_metrics.d.ts.map +1 -0
- package/dest/prover-agent/queue_metrics.js +5 -6
- package/dest/prover-agent/rpc.d.ts +11 -0
- package/dest/prover-agent/rpc.d.ts.map +1 -0
- package/dest/prover-agent/rpc.js +4 -6
- package/dest/prover-client/factory.d.ts +6 -0
- package/dest/prover-client/factory.d.ts.map +1 -0
- package/dest/prover-client/factory.js +1 -0
- package/dest/prover-client/index.d.ts +3 -0
- package/dest/prover-client/index.d.ts.map +1 -0
- package/dest/prover-client/index.js +1 -0
- package/dest/prover-client/prover-client.d.ts +42 -0
- package/dest/prover-client/prover-client.d.ts.map +1 -0
- package/dest/prover-client/prover-client.js +25 -30
- package/dest/prover-client/server-epoch-prover.d.ts +25 -0
- package/dest/prover-client/server-epoch-prover.d.ts.map +1 -0
- package/dest/prover-client/server-epoch-prover.js +4 -4
- package/dest/proving_broker/broker_prover_facade.d.ts +39 -0
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -0
- package/dest/proving_broker/broker_prover_facade.js +59 -70
- package/dest/proving_broker/config.d.ts +61 -0
- package/dest/proving_broker/config.d.ts.map +1 -0
- package/dest/proving_broker/config.js +37 -22
- package/dest/proving_broker/factory.d.ts +5 -0
- package/dest/proving_broker/factory.d.ts.map +1 -0
- package/dest/proving_broker/factory.js +2 -1
- package/dest/proving_broker/fixtures.d.ts +5 -0
- package/dest/proving_broker/fixtures.d.ts.map +1 -0
- package/dest/proving_broker/fixtures.js +1 -0
- package/dest/proving_broker/index.d.ts +10 -0
- package/dest/proving_broker/index.d.ts.map +1 -0
- package/dest/proving_broker/index.js +1 -0
- package/dest/proving_broker/proof_store/factory.d.ts +6 -0
- package/dest/proving_broker/proof_store/factory.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/factory.js +12 -9
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +13 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.js +7 -11
- package/dest/proving_broker/proof_store/index.d.ts +4 -0
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/index.js +1 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts +14 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/inline_proof_store.js +7 -11
- package/dest/proving_broker/proof_store/proof_store.d.ts +35 -0
- package/dest/proving_broker/proof_store/proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/proof_store.js +2 -3
- package/dest/proving_broker/proving_agent.d.ts +44 -0
- package/dest/proving_broker/proving_agent.d.ts.map +1 -0
- package/dest/proving_broker/proving_agent.js +110 -121
- package/dest/proving_broker/proving_agent_instrumentation.d.ts +8 -0
- package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +1 -0
- package/dest/proving_broker/proving_agent_instrumentation.js +3 -3
- package/dest/proving_broker/proving_broker.d.ts +75 -0
- package/dest/proving_broker/proving_broker.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker.js +451 -491
- package/dest/proving_broker/proving_broker_database/memory.d.ts +16 -0
- package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database/memory.js +13 -19
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +21 -0
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database/persisted.js +21 -41
- package/dest/proving_broker/proving_broker_database.d.ts +39 -0
- package/dest/proving_broker/proving_broker_database.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database.js +2 -3
- package/dest/proving_broker/proving_broker_instrumentation.d.ts +25 -0
- package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_instrumentation.js +21 -28
- package/dest/proving_broker/proving_job_controller.d.ts +31 -0
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -0
- package/dest/proving_broker/proving_job_controller.js +62 -81
- package/dest/proving_broker/rpc.d.ts +11 -0
- package/dest/proving_broker/rpc.d.ts.map +1 -0
- package/dest/proving_broker/rpc.js +15 -23
- package/dest/test/mock_prover.d.ts +33 -0
- package/dest/test/mock_prover.d.ts.map +1 -0
- package/dest/test/mock_prover.js +9 -11
- package/package.json +11 -12
- package/src/index.ts +1 -1
- package/src/orchestrator/block-building-helpers.ts +1 -1
- package/src/proving_broker/proving_agent.ts +11 -30
- package/src/proving_broker/proving_broker.ts +27 -53
- package/src/proving_broker/rpc.ts +2 -8
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { ConstantRollupData, PrivateBaseRollupHints, PrivateBaseStateDiffHints, PublicBaseRollupHints, PublicBaseStateDiffHints } from '@aztec/circuits.js/rollup';
|
|
1
|
+
import { Body, MerkleTreeId, TxEffect, getTreeHeight, } from '@aztec/circuit-types';
|
|
2
|
+
import { ARCHIVE_HEIGHT, AppendOnlyTreeSnapshot, BlockHeader, ContentCommitment, Fr, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, MerkleTreeCalculator, NOTE_HASH_SUBTREE_HEIGHT, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NullifierLeafPreimage, PUBLIC_DATA_TREE_HEIGHT, PartialStateReference, PublicDataHint, PublicDataTreeLeaf, PublicDataTreeLeafPreimage, StateReference, } from '@aztec/circuits.js';
|
|
3
|
+
import { ConstantRollupData, PrivateBaseRollupHints, PrivateBaseStateDiffHints, PublicBaseRollupHints, PublicBaseStateDiffHints, } from '@aztec/circuits.js/rollup';
|
|
5
4
|
import { makeTuple } from '@aztec/foundation/array';
|
|
5
|
+
import { Blob } from '@aztec/foundation/blob';
|
|
6
6
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
7
7
|
import { sha256Trunc } from '@aztec/foundation/crypto';
|
|
8
8
|
import { assertLength, serializeToBuffer, toFriendlyJSON } from '@aztec/foundation/serialize';
|
|
@@ -13,14 +13,14 @@ import { computeFeePayerBalanceLeafSlot } from '@aztec/simulator/server';
|
|
|
13
13
|
import { Attributes, runInSpan } from '@aztec/telemetry-client';
|
|
14
14
|
import { inspect } from 'util';
|
|
15
15
|
// Builds the hints for base rollup. Updating the contract, nullifier, and data trees in the process.
|
|
16
|
-
export const buildBaseRollupHints = runInSpan('BlockBuilderHelpers', 'buildBaseRollupHints', async (span, tx, globalVariables, db, startSpongeBlob)=>{
|
|
16
|
+
export const buildBaseRollupHints = runInSpan('BlockBuilderHelpers', 'buildBaseRollupHints', async (span, tx, globalVariables, db, startSpongeBlob) => {
|
|
17
17
|
span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
|
|
18
18
|
// Get trees info before any changes hit
|
|
19
19
|
const constants = await getConstantRollupData(globalVariables, db);
|
|
20
20
|
const start = new PartialStateReference(await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db), await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db), await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db));
|
|
21
21
|
// Get the subtree sibling paths for the circuit
|
|
22
22
|
const noteHashSubtreeSiblingPathArray = await getSubtreeSiblingPath(MerkleTreeId.NOTE_HASH_TREE, NOTE_HASH_SUBTREE_HEIGHT, db);
|
|
23
|
-
const noteHashSubtreeSiblingPath = makeTuple(NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH,
|
|
23
|
+
const noteHashSubtreeSiblingPath = makeTuple(NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, i => i < noteHashSubtreeSiblingPathArray.length ? noteHashSubtreeSiblingPathArray[i] : Fr.ZERO);
|
|
24
24
|
// Update the note hash trees with the new items being inserted to get the new roots
|
|
25
25
|
// that will be used by the next iteration of the base rollup circuit, skipping the empty ones
|
|
26
26
|
const noteHashes = padArrayEnd(tx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX);
|
|
@@ -29,29 +29,33 @@ export const buildBaseRollupHints = runInSpan('BlockBuilderHelpers', 'buildBaseR
|
|
|
29
29
|
// All reads that refer to writes in the same tx are transient and can be simplified out.
|
|
30
30
|
const txPublicDataUpdateRequestInfo = await processPublicDataUpdateRequests(tx, db);
|
|
31
31
|
// Update the nullifier tree, capturing the low nullifier info for each individual operation
|
|
32
|
-
const { lowLeavesWitnessData: nullifierWitnessLeaves, newSubtreeSiblingPath: nullifiersSubtreeSiblingPath, sortedNewLeaves: sortednullifiers, sortedNewLeavesIndexes } = await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, padArrayEnd(tx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(
|
|
32
|
+
const { lowLeavesWitnessData: nullifierWitnessLeaves, newSubtreeSiblingPath: nullifiersSubtreeSiblingPath, sortedNewLeaves: sortednullifiers, sortedNewLeavesIndexes, } = await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, padArrayEnd(tx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()), NULLIFIER_SUBTREE_HEIGHT);
|
|
33
33
|
if (nullifierWitnessLeaves === undefined) {
|
|
34
34
|
throw new Error(`Could not craft nullifier batch insertion proofs`);
|
|
35
35
|
}
|
|
36
36
|
// Extract witness objects from returned data
|
|
37
|
-
const nullifierPredecessorMembershipWitnessesWithoutPadding = nullifierWitnessLeaves.map(
|
|
37
|
+
const nullifierPredecessorMembershipWitnessesWithoutPadding = nullifierWitnessLeaves.map(l => MembershipWitness.fromBufferArray(l.index, assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT)));
|
|
38
38
|
const nullifierSubtreeSiblingPathArray = nullifiersSubtreeSiblingPath.toFields();
|
|
39
|
-
const nullifierSubtreeSiblingPath = makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH,
|
|
39
|
+
const nullifierSubtreeSiblingPath = makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, i => i < nullifierSubtreeSiblingPathArray.length ? nullifierSubtreeSiblingPathArray[i] : Fr.ZERO);
|
|
40
40
|
// Append new data to startSpongeBlob
|
|
41
41
|
const inputSpongeBlob = startSpongeBlob.clone();
|
|
42
42
|
await startSpongeBlob.absorb(tx.txEffect.toBlobFields());
|
|
43
43
|
if (tx.avmProvingRequest) {
|
|
44
44
|
// Build public base rollup hints
|
|
45
45
|
const stateDiffHints = PublicBaseStateDiffHints.from({
|
|
46
|
-
nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX, i => i < nullifierWitnessLeaves.length
|
|
47
|
+
? nullifierWitnessLeaves[i].leafPreimage
|
|
48
|
+
: NullifierLeafPreimage.empty()),
|
|
49
|
+
nullifierPredecessorMembershipWitnesses: makeTuple(MAX_NULLIFIERS_PER_TX, i => i < nullifierPredecessorMembershipWitnessesWithoutPadding.length
|
|
50
|
+
? nullifierPredecessorMembershipWitnessesWithoutPadding[i]
|
|
51
|
+
: makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT)),
|
|
52
|
+
sortedNullifiers: makeTuple(MAX_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortednullifiers[i])),
|
|
53
|
+
sortedNullifierIndexes: makeTuple(MAX_NULLIFIERS_PER_TX, i => sortedNewLeavesIndexes[i]),
|
|
50
54
|
noteHashSubtreeSiblingPath,
|
|
51
55
|
nullifierSubtreeSiblingPath,
|
|
52
56
|
lowPublicDataWritesPreimages: padArrayEnd(txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages, PublicDataTreeLeafPreimage.empty(), MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX),
|
|
53
57
|
lowPublicDataWritesMembershipWitnesses: padArrayEnd(txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses, MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT), MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX),
|
|
54
|
-
publicDataTreeSiblingPaths: padArrayEnd(txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths, makeTuple(PUBLIC_DATA_TREE_HEIGHT, ()=>Fr.ZERO), MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX)
|
|
58
|
+
publicDataTreeSiblingPaths: padArrayEnd(txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths, makeTuple(PUBLIC_DATA_TREE_HEIGHT, () => Fr.ZERO), MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX),
|
|
55
59
|
});
|
|
56
60
|
const blockHash = await tx.constants.historicalHeader.hash();
|
|
57
61
|
const archiveRootMembershipWitness = await getMembershipWitnessFor(blockHash, MerkleTreeId.ARCHIVE, ARCHIVE_HEIGHT, db);
|
|
@@ -60,29 +64,40 @@ export const buildBaseRollupHints = runInSpan('BlockBuilderHelpers', 'buildBaseR
|
|
|
60
64
|
startSpongeBlob: inputSpongeBlob,
|
|
61
65
|
stateDiffHints,
|
|
62
66
|
archiveRootMembershipWitness,
|
|
63
|
-
constants
|
|
67
|
+
constants,
|
|
64
68
|
});
|
|
65
|
-
}
|
|
66
|
-
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
if (txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses.length > 1 ||
|
|
72
|
+
txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages.length > 1 ||
|
|
73
|
+
txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths.length > 1) {
|
|
67
74
|
throw new Error(`More than one public data write in a private only tx`);
|
|
68
75
|
}
|
|
69
76
|
// Create data hint for reading fee payer initial balance in Fee Juice
|
|
70
77
|
// If no fee payer is set, read hint should be empty
|
|
71
78
|
const leafSlot = await computeFeePayerBalanceLeafSlot(tx.data.feePayer);
|
|
72
|
-
const feePayerFeeJuiceBalanceReadHint = tx.data.feePayer.isZero()
|
|
79
|
+
const feePayerFeeJuiceBalanceReadHint = tx.data.feePayer.isZero()
|
|
80
|
+
? PublicDataHint.empty()
|
|
81
|
+
: await getPublicDataHint(db, leafSlot.toBigInt());
|
|
73
82
|
const feeWriteLowLeafPreimage = txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages[0] || PublicDataTreeLeafPreimage.empty();
|
|
74
|
-
const feeWriteLowLeafMembershipWitness = txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses[0] ||
|
|
75
|
-
|
|
83
|
+
const feeWriteLowLeafMembershipWitness = txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses[0] ||
|
|
84
|
+
MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT);
|
|
85
|
+
const feeWriteSiblingPath = txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths[0] ||
|
|
86
|
+
makeTuple(PUBLIC_DATA_TREE_HEIGHT, () => Fr.ZERO);
|
|
76
87
|
const stateDiffHints = PrivateBaseStateDiffHints.from({
|
|
77
|
-
nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX, i => i < nullifierWitnessLeaves.length
|
|
89
|
+
? nullifierWitnessLeaves[i].leafPreimage
|
|
90
|
+
: NullifierLeafPreimage.empty()),
|
|
91
|
+
nullifierPredecessorMembershipWitnesses: makeTuple(MAX_NULLIFIERS_PER_TX, i => i < nullifierPredecessorMembershipWitnessesWithoutPadding.length
|
|
92
|
+
? nullifierPredecessorMembershipWitnessesWithoutPadding[i]
|
|
93
|
+
: makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT)),
|
|
94
|
+
sortedNullifiers: makeTuple(MAX_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortednullifiers[i])),
|
|
95
|
+
sortedNullifierIndexes: makeTuple(MAX_NULLIFIERS_PER_TX, i => sortedNewLeavesIndexes[i]),
|
|
81
96
|
noteHashSubtreeSiblingPath,
|
|
82
97
|
nullifierSubtreeSiblingPath,
|
|
83
98
|
feeWriteLowLeafPreimage,
|
|
84
99
|
feeWriteLowLeafMembershipWitness,
|
|
85
|
-
feeWriteSiblingPath
|
|
100
|
+
feeWriteSiblingPath,
|
|
86
101
|
});
|
|
87
102
|
const blockHash = await tx.constants.historicalHeader.hash();
|
|
88
103
|
const archiveRootMembershipWitness = await getMembershipWitnessFor(blockHash, MerkleTreeId.ARCHIVE, ARCHIVE_HEIGHT, db);
|
|
@@ -92,18 +107,18 @@ export const buildBaseRollupHints = runInSpan('BlockBuilderHelpers', 'buildBaseR
|
|
|
92
107
|
stateDiffHints,
|
|
93
108
|
feePayerFeeJuiceBalanceReadHint: feePayerFeeJuiceBalanceReadHint,
|
|
94
109
|
archiveRootMembershipWitness,
|
|
95
|
-
constants
|
|
110
|
+
constants,
|
|
96
111
|
});
|
|
97
112
|
}
|
|
98
113
|
});
|
|
99
114
|
export async function getPublicDataHint(db, leafSlot) {
|
|
100
|
-
const { index } = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot) ?? {};
|
|
115
|
+
const { index } = (await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot)) ?? {};
|
|
101
116
|
if (index === undefined) {
|
|
102
117
|
throw new Error(`Cannot find the previous value index for public data ${leafSlot}.`);
|
|
103
118
|
}
|
|
104
119
|
const siblingPath = await db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, index);
|
|
105
120
|
const membershipWitness = new MembershipWitness(PUBLIC_DATA_TREE_HEIGHT, index, siblingPath.toTuple());
|
|
106
|
-
const leafPreimage = await db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, index);
|
|
121
|
+
const leafPreimage = (await db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, index));
|
|
107
122
|
if (!leafPreimage) {
|
|
108
123
|
throw new Error(`Cannot find the leaf preimage for public data tree at index ${index}.`);
|
|
109
124
|
}
|
|
@@ -111,90 +126,76 @@ export async function getPublicDataHint(db, leafSlot) {
|
|
|
111
126
|
const value = exists ? leafPreimage.value : Fr.ZERO;
|
|
112
127
|
return new PublicDataHint(new Fr(leafSlot), value, membershipWitness, leafPreimage);
|
|
113
128
|
}
|
|
114
|
-
export const buildBlobHints = runInSpan('BlockBuilderHelpers', 'buildBlobHints', async (_span, txEffects)=>{
|
|
115
|
-
const blobFields = txEffects.flatMap(
|
|
129
|
+
export const buildBlobHints = runInSpan('BlockBuilderHelpers', 'buildBlobHints', async (_span, txEffects) => {
|
|
130
|
+
const blobFields = txEffects.flatMap(tx => tx.toBlobFields());
|
|
116
131
|
const blobs = await Blob.getBlobs(blobFields);
|
|
117
|
-
const blobCommitments = blobs.map(
|
|
132
|
+
const blobCommitments = blobs.map(b => b.commitmentToFields());
|
|
118
133
|
const blobsHash = new Fr(getBlobsHashFromBlobs(blobs));
|
|
119
|
-
return {
|
|
120
|
-
blobFields,
|
|
121
|
-
blobCommitments,
|
|
122
|
-
blobs,
|
|
123
|
-
blobsHash
|
|
124
|
-
};
|
|
134
|
+
return { blobFields, blobCommitments, blobs, blobsHash };
|
|
125
135
|
});
|
|
126
|
-
export const buildHeaderFromCircuitOutputs = runInSpan('BlockBuilderHelpers', 'buildHeaderFromCircuitOutputs', async (_span, previousRollupData, parityPublicInputs, rootRollupOutputs, endState, logger)=>{
|
|
136
|
+
export const buildHeaderFromCircuitOutputs = runInSpan('BlockBuilderHelpers', 'buildHeaderFromCircuitOutputs', async (_span, previousRollupData, parityPublicInputs, rootRollupOutputs, endState, logger) => {
|
|
127
137
|
if (previousRollupData.length > 2) {
|
|
128
138
|
throw new Error(`There can't be more than 2 previous rollups. Received ${previousRollupData.length}.`);
|
|
129
139
|
}
|
|
130
140
|
const blobsHash = rootRollupOutputs.blobPublicInputs[0].getBlobsHash();
|
|
131
|
-
const numTxs = previousRollupData.reduce((sum, d)=>sum + d.numTxs, 0);
|
|
132
|
-
const outHash = previousRollupData.length === 0
|
|
133
|
-
|
|
134
|
-
previousRollupData
|
|
135
|
-
|
|
141
|
+
const numTxs = previousRollupData.reduce((sum, d) => sum + d.numTxs, 0);
|
|
142
|
+
const outHash = previousRollupData.length === 0
|
|
143
|
+
? Fr.ZERO.toBuffer()
|
|
144
|
+
: previousRollupData.length === 1
|
|
145
|
+
? previousRollupData[0].outHash.toBuffer()
|
|
146
|
+
: sha256Trunc(Buffer.concat([previousRollupData[0].outHash.toBuffer(), previousRollupData[1].outHash.toBuffer()]));
|
|
136
147
|
const contentCommitment = new ContentCommitment(new Fr(numTxs), blobsHash, parityPublicInputs.shaRoot.toBuffer(), outHash);
|
|
137
|
-
const accumulatedFees = previousRollupData.reduce((sum, d)=>sum.add(d.accumulatedFees), Fr.ZERO);
|
|
138
|
-
const accumulatedManaUsed = previousRollupData.reduce((sum, d)=>sum.add(d.accumulatedManaUsed), Fr.ZERO);
|
|
148
|
+
const accumulatedFees = previousRollupData.reduce((sum, d) => sum.add(d.accumulatedFees), Fr.ZERO);
|
|
149
|
+
const accumulatedManaUsed = previousRollupData.reduce((sum, d) => sum.add(d.accumulatedManaUsed), Fr.ZERO);
|
|
139
150
|
const header = new BlockHeader(rootRollupOutputs.previousArchive, contentCommitment, endState, rootRollupOutputs.endGlobalVariables, accumulatedFees, accumulatedManaUsed);
|
|
140
151
|
if (!(await header.hash()).equals(rootRollupOutputs.endBlockHash)) {
|
|
141
|
-
logger?.error(`Block header mismatch when building header from circuit outputs.` +
|
|
152
|
+
logger?.error(`Block header mismatch when building header from circuit outputs.` +
|
|
153
|
+
`\n\nHeader: ${inspect(header)}` +
|
|
154
|
+
`\n\nCircuit: ${toFriendlyJSON(rootRollupOutputs)}`);
|
|
142
155
|
throw new Error(`Block header mismatch when building from circuit outputs`);
|
|
143
156
|
}
|
|
144
157
|
return header;
|
|
145
158
|
});
|
|
146
|
-
export const buildHeaderAndBodyFromTxs = runInSpan('BlockBuilderHelpers', 'buildHeaderAndBodyFromTxs', async (span, txs, globalVariables, l1ToL2Messages, db)=>{
|
|
159
|
+
export const buildHeaderAndBodyFromTxs = runInSpan('BlockBuilderHelpers', 'buildHeaderAndBodyFromTxs', async (span, txs, globalVariables, l1ToL2Messages, db) => {
|
|
147
160
|
span.setAttribute(Attributes.BLOCK_NUMBER, globalVariables.blockNumber.toNumber());
|
|
148
161
|
const stateReference = new StateReference(await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db), new PartialStateReference(await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db), await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db), await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db)));
|
|
149
162
|
const previousArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
150
|
-
const txEffects = txs.map(
|
|
163
|
+
const txEffects = txs.map(tx => tx.txEffect);
|
|
151
164
|
const body = new Body(txEffects);
|
|
152
165
|
const numTxs = body.txEffects.length;
|
|
153
|
-
const outHash = numTxs === 0
|
|
166
|
+
const outHash = numTxs === 0
|
|
167
|
+
? Fr.ZERO.toBuffer()
|
|
168
|
+
: numTxs === 1
|
|
169
|
+
? body.txEffects[0].txOutHash()
|
|
170
|
+
: computeUnbalancedMerkleRoot(body.txEffects.map(tx => tx.txOutHash()), TxEffect.empty().txOutHash());
|
|
154
171
|
l1ToL2Messages = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
155
|
-
const hasher = (left, right)=>Promise.resolve(sha256Trunc(Buffer.concat([
|
|
156
|
-
left,
|
|
157
|
-
right
|
|
158
|
-
])));
|
|
172
|
+
const hasher = (left, right) => Promise.resolve(sha256Trunc(Buffer.concat([left, right])));
|
|
159
173
|
const parityHeight = Math.ceil(Math.log2(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP));
|
|
160
174
|
const parityCalculator = await MerkleTreeCalculator.create(parityHeight, Fr.ZERO.toBuffer(), hasher);
|
|
161
|
-
const parityShaRoot = await parityCalculator.computeTreeRoot(l1ToL2Messages.map(
|
|
175
|
+
const parityShaRoot = await parityCalculator.computeTreeRoot(l1ToL2Messages.map(msg => msg.toBuffer()));
|
|
162
176
|
const blobsHash = getBlobsHashFromBlobs(await Blob.getBlobs(body.toBlobFields()));
|
|
163
177
|
const contentCommitment = new ContentCommitment(new Fr(numTxs), blobsHash, parityShaRoot, outHash);
|
|
164
|
-
const fees = body.txEffects.reduce((acc, tx)=>acc.add(tx.transactionFee), Fr.ZERO);
|
|
165
|
-
const manaUsed = txs.reduce((acc, tx)=>acc.add(new Fr(tx.gasUsed.totalGas.l2Gas)), Fr.ZERO);
|
|
178
|
+
const fees = body.txEffects.reduce((acc, tx) => acc.add(tx.transactionFee), Fr.ZERO);
|
|
179
|
+
const manaUsed = txs.reduce((acc, tx) => acc.add(new Fr(tx.gasUsed.totalGas.l2Gas)), Fr.ZERO);
|
|
166
180
|
const header = new BlockHeader(previousArchive, contentCommitment, stateReference, globalVariables, fees, manaUsed);
|
|
167
|
-
return {
|
|
168
|
-
header,
|
|
169
|
-
body
|
|
170
|
-
};
|
|
181
|
+
return { header, body };
|
|
171
182
|
});
|
|
172
183
|
export function getBlobsHashFromBlobs(inputs) {
|
|
173
|
-
const blobHashes = serializeToBuffer(inputs.map(
|
|
184
|
+
const blobHashes = serializeToBuffer(inputs.map(b => b.getEthVersionedBlobHash()));
|
|
174
185
|
return sha256Trunc(serializeToBuffer(blobHashes));
|
|
175
186
|
}
|
|
176
187
|
// Validate that the roots of all local trees match the output of the root circuit simulation
|
|
177
188
|
export async function validateBlockRootOutput(blockRootOutput, blockHeader, db) {
|
|
178
189
|
await Promise.all([
|
|
179
190
|
validateState(blockHeader.state, db),
|
|
180
|
-
validateSimulatedTree(await getTreeSnapshot(MerkleTreeId.ARCHIVE, db), blockRootOutput.newArchive, 'Archive')
|
|
191
|
+
validateSimulatedTree(await getTreeSnapshot(MerkleTreeId.ARCHIVE, db), blockRootOutput.newArchive, 'Archive'),
|
|
181
192
|
]);
|
|
182
193
|
}
|
|
183
|
-
export const validateState = runInSpan('BlockBuilderHelpers', 'validateState', async (_span, state, db)=>{
|
|
184
|
-
const promises = [
|
|
185
|
-
|
|
186
|
-
MerkleTreeId.NULLIFIER_TREE,
|
|
187
|
-
MerkleTreeId.PUBLIC_DATA_TREE
|
|
188
|
-
].map(async (id)=>{
|
|
189
|
-
return {
|
|
190
|
-
key: id,
|
|
191
|
-
value: await getTreeSnapshot(id, db)
|
|
192
|
-
};
|
|
194
|
+
export const validateState = runInSpan('BlockBuilderHelpers', 'validateState', async (_span, state, db) => {
|
|
195
|
+
const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(async (id) => {
|
|
196
|
+
return { key: id, value: await getTreeSnapshot(id, db) };
|
|
193
197
|
});
|
|
194
|
-
const snapshots = new Map((await Promise.all(promises)).map(
|
|
195
|
-
obj.key,
|
|
196
|
-
obj.value
|
|
197
|
-
]));
|
|
198
|
+
const snapshots = new Map((await Promise.all(promises)).map(obj => [obj.key, obj.value]));
|
|
198
199
|
validatePartialState(state.partial, snapshots);
|
|
199
200
|
validateSimulatedTree(await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db), state.l1ToL2MessageTree, 'L1ToL2MessageTree');
|
|
200
201
|
});
|
|
@@ -203,12 +204,12 @@ export async function getRootTreeSiblingPath(treeId, db) {
|
|
|
203
204
|
const path = await db.getSiblingPath(treeId, size);
|
|
204
205
|
return padArrayEnd(path.toFields(), Fr.ZERO, getTreeHeight(treeId));
|
|
205
206
|
}
|
|
206
|
-
export const getConstantRollupData = runInSpan('BlockBuilderHelpers', 'getConstantRollupData', async (_span, globalVariables, db)=>{
|
|
207
|
+
export const getConstantRollupData = runInSpan('BlockBuilderHelpers', 'getConstantRollupData', async (_span, globalVariables, db) => {
|
|
207
208
|
return ConstantRollupData.from({
|
|
208
209
|
vkTreeRoot: await getVKTreeRoot(),
|
|
209
210
|
protocolContractTreeRoot,
|
|
210
211
|
lastArchive: await getTreeSnapshot(MerkleTreeId.ARCHIVE, db),
|
|
211
|
-
globalVariables
|
|
212
|
+
globalVariables,
|
|
212
213
|
});
|
|
213
214
|
});
|
|
214
215
|
export async function getTreeSnapshot(id, db) {
|
|
@@ -216,20 +217,20 @@ export async function getTreeSnapshot(id, db) {
|
|
|
216
217
|
return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size));
|
|
217
218
|
}
|
|
218
219
|
export function makeEmptyMembershipWitness(height) {
|
|
219
|
-
return new MembershipWitness(height, 0n, makeTuple(height, ()=>Fr.ZERO));
|
|
220
|
+
return new MembershipWitness(height, 0n, makeTuple(height, () => Fr.ZERO));
|
|
220
221
|
}
|
|
221
|
-
const processPublicDataUpdateRequests = runInSpan('BlockBuilderHelpers', 'processPublicDataUpdateRequests', async (span, tx, db)=>{
|
|
222
|
+
const processPublicDataUpdateRequests = runInSpan('BlockBuilderHelpers', 'processPublicDataUpdateRequests', async (span, tx, db) => {
|
|
222
223
|
span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
|
|
223
|
-
const allPublicDataWrites = tx.txEffect.publicDataWrites.map(({ leafSlot, value })=>new PublicDataTreeLeaf(leafSlot, value));
|
|
224
|
-
const { lowLeavesWitnessData, insertionWitnessData } = await db.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, allPublicDataWrites.map(
|
|
224
|
+
const allPublicDataWrites = tx.txEffect.publicDataWrites.map(({ leafSlot, value }) => new PublicDataTreeLeaf(leafSlot, value));
|
|
225
|
+
const { lowLeavesWitnessData, insertionWitnessData } = await db.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, allPublicDataWrites.map(write => {
|
|
225
226
|
if (write.isEmpty()) {
|
|
226
227
|
throw new Error(`Empty public data write in tx: ${toFriendlyJSON(tx)}`);
|
|
227
228
|
}
|
|
228
229
|
return write.toBuffer();
|
|
229
230
|
}));
|
|
230
|
-
const lowPublicDataWritesPreimages = lowLeavesWitnessData.map(
|
|
231
|
-
const lowPublicDataWritesMembershipWitnesses = lowLeavesWitnessData.map(
|
|
232
|
-
const publicDataWritesSiblingPaths = insertionWitnessData.map(
|
|
231
|
+
const lowPublicDataWritesPreimages = lowLeavesWitnessData.map(lowLeafWitness => lowLeafWitness.leafPreimage);
|
|
232
|
+
const lowPublicDataWritesMembershipWitnesses = lowLeavesWitnessData.map(lowLeafWitness => MembershipWitness.fromBufferArray(lowLeafWitness.index, assertLength(lowLeafWitness.siblingPath.toBufferArray(), PUBLIC_DATA_TREE_HEIGHT)));
|
|
233
|
+
const publicDataWritesSiblingPaths = insertionWitnessData.map(w => {
|
|
233
234
|
const insertionSiblingPath = w.siblingPath.toFields();
|
|
234
235
|
assertLength(insertionSiblingPath, PUBLIC_DATA_TREE_HEIGHT);
|
|
235
236
|
return insertionSiblingPath;
|
|
@@ -237,11 +238,11 @@ const processPublicDataUpdateRequests = runInSpan('BlockBuilderHelpers', 'proces
|
|
|
237
238
|
return {
|
|
238
239
|
lowPublicDataWritesPreimages,
|
|
239
240
|
lowPublicDataWritesMembershipWitnesses,
|
|
240
|
-
publicDataWritesSiblingPaths
|
|
241
|
+
publicDataWritesSiblingPaths,
|
|
241
242
|
};
|
|
242
243
|
});
|
|
243
244
|
export async function getSubtreeSiblingPath(treeId, subtreeHeight, db) {
|
|
244
|
-
const nextAvailableLeafIndex = await db.getTreeInfo(treeId).then(
|
|
245
|
+
const nextAvailableLeafIndex = await db.getTreeInfo(treeId).then(t => t.size);
|
|
245
246
|
const fullSiblingPath = await db.getSiblingPath(treeId, nextAvailableLeafIndex);
|
|
246
247
|
// Drop the first subtreeHeight items since we only care about the path to the subtree root
|
|
247
248
|
return fullSiblingPath.getSubtreeSiblingPath(subtreeHeight).toFields();
|
|
@@ -252,9 +253,7 @@ export async function getMembershipWitnessFor(value, treeId, height, db) {
|
|
|
252
253
|
if (value.isZero()) {
|
|
253
254
|
return makeEmptyMembershipWitness(height);
|
|
254
255
|
}
|
|
255
|
-
const index = (await db.findLeafIndices(treeId, [
|
|
256
|
-
value.toBuffer()
|
|
257
|
-
]))[0];
|
|
256
|
+
const index = (await db.findLeafIndices(treeId, [value.toBuffer()]))[0];
|
|
258
257
|
if (index === undefined) {
|
|
259
258
|
throw new Error(`Leaf with value ${value} not found in tree ${MerkleTreeId[treeId]}`);
|
|
260
259
|
}
|
|
@@ -290,3 +289,4 @@ export function validateTx(tx) {
|
|
|
290
289
|
throw new Error(`Empty public data tree in tx: ${toFriendlyJSON(tx)}`);
|
|
291
290
|
}
|
|
292
291
|
}
|
|
292
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2stYnVpbGRpbmctaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcmNoZXN0cmF0b3IvYmxvY2stYnVpbGRpbmctaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsSUFBSSxFQUNKLFlBQVksRUFHWixRQUFRLEVBQ1IsYUFBYSxHQUNkLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUNMLGNBQWMsRUFDZCxzQkFBc0IsRUFDdEIsV0FBVyxFQUNYLGlCQUFpQixFQUNqQixFQUFFLEVBRUYsc0JBQXNCLEVBQ3RCLHFCQUFxQixFQUNyQiw0Q0FBNEMsRUFDNUMsaUJBQWlCLEVBQ2pCLG9CQUFvQixFQUNwQix3QkFBd0IsRUFDeEIscUNBQXFDLEVBQ3JDLHdCQUF3QixFQUN4QixxQ0FBcUMsRUFDckMscUJBQXFCLEVBQ3JCLG1DQUFtQyxFQUNuQyxxQkFBcUIsRUFDckIsdUJBQXVCLEVBRXZCLHFCQUFxQixFQUNyQixjQUFjLEVBQ2Qsa0JBQWtCLEVBQ2xCLDBCQUEwQixFQUMxQixjQUFjLEdBQ2YsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QixPQUFPLEVBR0wsa0JBQWtCLEVBQ2xCLHNCQUFzQixFQUN0Qix5QkFBeUIsRUFDekIscUJBQXFCLEVBQ3JCLHdCQUF3QixHQUN6QixNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzNELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUV2RCxPQUFPLEVBQWMsWUFBWSxFQUFFLGlCQUFpQixFQUFFLGNBQWMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzFHLE9BQU8sRUFBRSwyQkFBMkIsRUFB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
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type L2Block, type MerkleTreeId, type PublicInputsAndRecursiveProof } from '@aztec/circuit-types';
|
|
2
|
+
import { type ARCHIVE_HEIGHT, type AppendOnlyTreeSnapshot, type BlockHeader, Fr, type GlobalVariables, type L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, type ParityPublicInputs, RootParityInputs } from '@aztec/circuits.js';
|
|
3
|
+
import { SpongeBlob } from '@aztec/circuits.js/blobs';
|
|
4
|
+
import { type BaseOrMergeRollupPublicInputs, type BlockRootOrBlockMergePublicInputs, BlockRootRollupInputs, EmptyBlockRootRollupInputs, MergeRollupInputs, SingleTxBlockRootRollupInputs } from '@aztec/circuits.js/rollup';
|
|
5
|
+
import { type Logger } from '@aztec/foundation/log';
|
|
6
|
+
import { type Tuple } from '@aztec/foundation/serialize';
|
|
7
|
+
import { type TreeNodeLocation } from '@aztec/foundation/trees';
|
|
8
|
+
import { type EpochProvingState } from './epoch-proving-state.js';
|
|
9
|
+
import { type TxProvingState } from './tx-proving-state.js';
|
|
10
|
+
export type TreeSnapshots = Map<MerkleTreeId, AppendOnlyTreeSnapshot>;
|
|
11
|
+
/**
|
|
12
|
+
* The current state of the proving schedule for a given block. Managed by ProvingState.
|
|
13
|
+
* Contains the raw inputs and intermediate state to generate every constituent proof in the tree.
|
|
14
|
+
*/
|
|
15
|
+
export declare class BlockProvingState {
|
|
16
|
+
#private;
|
|
17
|
+
readonly index: number;
|
|
18
|
+
readonly globalVariables: GlobalVariables;
|
|
19
|
+
readonly newL1ToL2Messages: Fr[];
|
|
20
|
+
private readonly l1ToL2MessageSubtreeSiblingPath;
|
|
21
|
+
private readonly l1ToL2MessageTreeSnapshotAfterInsertion;
|
|
22
|
+
private readonly lastArchiveSnapshot;
|
|
23
|
+
private readonly newArchiveSiblingPath;
|
|
24
|
+
private readonly previousBlockHeader;
|
|
25
|
+
private readonly parentEpoch;
|
|
26
|
+
private baseOrMergeProvingOutputs;
|
|
27
|
+
private baseParityProvingOutputs;
|
|
28
|
+
private rootParityProvingOutput;
|
|
29
|
+
private blockRootProvingOutput;
|
|
30
|
+
blockRootRollupStarted: boolean;
|
|
31
|
+
block: L2Block | undefined;
|
|
32
|
+
spongeBlobState: SpongeBlob | undefined;
|
|
33
|
+
totalNumTxs: number;
|
|
34
|
+
private txs;
|
|
35
|
+
error: string | undefined;
|
|
36
|
+
constructor(index: number, globalVariables: GlobalVariables, newL1ToL2Messages: Fr[], l1ToL2MessageSubtreeSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>, l1ToL2MessageTreeSnapshotAfterInsertion: AppendOnlyTreeSnapshot, lastArchiveSnapshot: AppendOnlyTreeSnapshot, newArchiveSiblingPath: Tuple<Fr, typeof ARCHIVE_HEIGHT>, previousBlockHeader: BlockHeader, parentEpoch: EpochProvingState);
|
|
37
|
+
get blockNumber(): number;
|
|
38
|
+
startNewBlock(numTxs: number, numBlobFields: number): void;
|
|
39
|
+
addNewTx(tx: TxProvingState): number;
|
|
40
|
+
setBaseRollupProof(txIndex: number, provingOutput: PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>): TreeNodeLocation;
|
|
41
|
+
setMergeRollupProof(location: TreeNodeLocation, provingOutput: PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>): void;
|
|
42
|
+
setBaseParityProof(index: number, provingOutput: PublicInputsAndRecursiveProof<ParityPublicInputs>): void;
|
|
43
|
+
setRootParityProof(provingOutput: PublicInputsAndRecursiveProof<ParityPublicInputs>): void;
|
|
44
|
+
setBlockRootRollupProof(provingOutput: PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>): void;
|
|
45
|
+
get allTxs(): TxProvingState[];
|
|
46
|
+
/** Returns the block number as an epoch number. Used for prioritizing proof requests. */
|
|
47
|
+
get epochNumber(): number;
|
|
48
|
+
getParentLocation(location: TreeNodeLocation): TreeNodeLocation;
|
|
49
|
+
getMergeRollupInputs(mergeLocation: TreeNodeLocation): Promise<MergeRollupInputs>;
|
|
50
|
+
getBlockRootRollupTypeAndInputs(proverId: Fr): Promise<{
|
|
51
|
+
rollupType: string;
|
|
52
|
+
inputs: EmptyBlockRootRollupInputs;
|
|
53
|
+
} | {
|
|
54
|
+
rollupType: string;
|
|
55
|
+
inputs: SingleTxBlockRootRollupInputs;
|
|
56
|
+
} | {
|
|
57
|
+
rollupType: string;
|
|
58
|
+
inputs: BlockRootRollupInputs;
|
|
59
|
+
}>;
|
|
60
|
+
getPaddingBlockRootInputs(proverId: Fr): Promise<EmptyBlockRootRollupInputs>;
|
|
61
|
+
getRootParityInputs(): Promise<RootParityInputs>;
|
|
62
|
+
getTxProvingState(txIndex: number): TxProvingState;
|
|
63
|
+
buildHeaderFromProvingOutputs(logger?: Logger): Promise<BlockHeader>;
|
|
64
|
+
isReadyForMergeRollup(location: TreeNodeLocation): boolean;
|
|
65
|
+
isReadyForBlockRootRollup(): boolean;
|
|
66
|
+
isReadyForRootParity(): boolean;
|
|
67
|
+
isComplete(): boolean;
|
|
68
|
+
verifyState(): boolean;
|
|
69
|
+
reject(reason: string): void;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=block-proving-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-proving-state.d.ts","sourceRoot":"","sources":["../../src/orchestrator/block-proving-state.ts"],"names":[],"mappings":"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"}
|