@aztec/prover-client 0.0.0-test.0 → 0.0.1-commit.03f7ef2
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/block-factory/index.d.ts +2 -0
- package/dest/block-factory/index.d.ts.map +1 -0
- package/dest/block-factory/light.d.ts +38 -0
- package/dest/block-factory/light.d.ts.map +1 -0
- package/dest/block-factory/light.js +108 -0
- package/dest/config.d.ts +8 -8
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +12 -2
- package/dest/index.d.ts +1 -1
- package/dest/light/index.d.ts +2 -0
- package/dest/light/index.d.ts.map +1 -0
- package/dest/light/index.js +1 -0
- package/dest/light/lightweight_checkpoint_builder.d.ts +36 -0
- package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -0
- package/dest/light/lightweight_checkpoint_builder.js +147 -0
- package/dest/mocks/fixtures.d.ts +8 -8
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +34 -16
- package/dest/mocks/test_context.d.ts +41 -32
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +138 -87
- package/dest/orchestrator/block-building-helpers.d.ts +37 -30
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +170 -189
- package/dest/orchestrator/block-proving-state.d.ts +70 -48
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +282 -177
- package/dest/orchestrator/checkpoint-proving-state.d.ts +63 -0
- package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/checkpoint-proving-state.js +210 -0
- package/dest/orchestrator/epoch-proving-state.d.ts +41 -27
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +143 -73
- package/dest/orchestrator/index.d.ts +1 -1
- package/dest/orchestrator/orchestrator.d.ts +36 -33
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +379 -250
- package/dest/orchestrator/orchestrator_metrics.d.ts +1 -1
- package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.d.ts +13 -11
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +23 -40
- package/dest/prover-client/factory.d.ts +1 -1
- package/dest/prover-client/index.d.ts +1 -1
- package/dest/prover-client/prover-client.d.ts +4 -4
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +5 -4
- package/dest/prover-client/server-epoch-prover.d.ts +16 -12
- package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
- package/dest/prover-client/server-epoch-prover.js +11 -11
- package/dest/proving_broker/broker_prover_facade.d.ts +23 -16
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +59 -40
- package/dest/proving_broker/config.d.ts +19 -10
- package/dest/proving_broker/config.d.ts.map +1 -1
- package/dest/proving_broker/config.js +23 -6
- package/dest/proving_broker/factory.d.ts +2 -2
- package/dest/proving_broker/factory.d.ts.map +1 -1
- package/dest/proving_broker/factory.js +5 -1
- package/dest/proving_broker/fixtures.d.ts +3 -2
- package/dest/proving_broker/fixtures.d.ts.map +1 -1
- package/dest/proving_broker/fixtures.js +3 -2
- package/dest/proving_broker/index.d.ts +1 -1
- package/dest/proving_broker/proof_store/factory.d.ts +2 -2
- package/dest/proving_broker/proof_store/factory.js +1 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +1 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.js +1 -0
- package/dest/proving_broker/proof_store/index.d.ts +2 -1
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/index.js +1 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts +1 -1
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/proof_store.d.ts +1 -1
- package/dest/proving_broker/proving_agent.d.ts +4 -4
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +83 -47
- package/dest/proving_broker/proving_agent_instrumentation.d.ts +1 -1
- package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.d.ts +13 -4
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +39 -23
- package/dest/proving_broker/proving_broker_database/memory.d.ts +3 -2
- package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/memory.js +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +3 -2
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.js +12 -10
- package/dest/proving_broker/proving_broker_database.d.ts +3 -2
- package/dest/proving_broker/proving_broker_database.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_instrumentation.d.ts +1 -1
- package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.d.ts +9 -9
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +87 -60
- package/dest/proving_broker/rpc.d.ts +4 -6
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +1 -4
- package/dest/test/mock_proof_store.d.ts +9 -0
- package/dest/test/mock_proof_store.d.ts.map +1 -0
- package/dest/test/mock_proof_store.js +10 -0
- package/dest/test/mock_prover.d.ts +23 -17
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +37 -19
- package/package.json +34 -31
- package/src/block-factory/index.ts +1 -0
- package/src/block-factory/light.ts +137 -0
- package/src/config.ts +25 -9
- package/src/light/index.ts +1 -0
- package/src/light/lightweight_checkpoint_builder.ts +198 -0
- package/src/mocks/fixtures.ts +44 -39
- package/src/mocks/test_context.ts +213 -116
- package/src/orchestrator/block-building-helpers.ts +258 -334
- package/src/orchestrator/block-proving-state.ts +325 -231
- package/src/orchestrator/checkpoint-proving-state.ts +303 -0
- package/src/orchestrator/epoch-proving-state.ts +191 -113
- package/src/orchestrator/orchestrator.ts +582 -314
- package/src/orchestrator/tx-proving-state.ts +49 -64
- package/src/prover-client/prover-client.ts +16 -14
- package/src/prover-client/server-epoch-prover.ts +40 -22
- package/src/proving_broker/broker_prover_facade.ts +205 -126
- package/src/proving_broker/config.ts +25 -7
- package/src/proving_broker/factory.ts +2 -1
- package/src/proving_broker/fixtures.ts +8 -3
- package/src/proving_broker/proof_store/factory.ts +1 -1
- package/src/proving_broker/proof_store/gcs_proof_store.ts +5 -1
- package/src/proving_broker/proof_store/index.ts +1 -0
- package/src/proving_broker/proof_store/inline_proof_store.ts +1 -1
- package/src/proving_broker/proving_agent.ts +89 -47
- package/src/proving_broker/proving_broker.ts +56 -33
- package/src/proving_broker/proving_broker_database/memory.ts +3 -2
- package/src/proving_broker/proving_broker_database/persisted.ts +14 -12
- package/src/proving_broker/proving_broker_database.ts +2 -1
- package/src/proving_broker/proving_job_controller.ts +92 -81
- package/src/proving_broker/rpc.ts +1 -6
- package/src/test/mock_proof_store.ts +14 -0
- package/src/test/mock_prover.ts +158 -59
- package/dest/bin/get-proof-inputs.d.ts +0 -2
- package/dest/bin/get-proof-inputs.d.ts.map +0 -1
- package/dest/bin/get-proof-inputs.js +0 -51
- package/dest/block_builder/index.d.ts +0 -6
- package/dest/block_builder/index.d.ts.map +0 -1
- package/dest/block_builder/light.d.ts +0 -33
- package/dest/block_builder/light.d.ts.map +0 -1
- package/dest/block_builder/light.js +0 -82
- package/src/bin/get-proof-inputs.ts +0 -59
- package/src/block_builder/index.ts +0 -6
- package/src/block_builder/light.ts +0 -101
- /package/dest/{block_builder → block-factory}/index.js +0 -0
|
@@ -1,62 +1,64 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BatchedBlobAccumulator,
|
|
3
|
+
SpongeBlob,
|
|
4
|
+
computeBlobsHashFromBlobs,
|
|
5
|
+
encodeBlockBlobData,
|
|
6
|
+
getBlobCommitmentsFromBlobs,
|
|
7
|
+
getBlobsPerL1Block,
|
|
8
|
+
} from '@aztec/blob-lib';
|
|
2
9
|
import {
|
|
3
10
|
ARCHIVE_HEIGHT,
|
|
11
|
+
CHONK_PROOF_LENGTH,
|
|
4
12
|
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
5
13
|
MAX_NOTE_HASHES_PER_TX,
|
|
6
14
|
MAX_NULLIFIERS_PER_TX,
|
|
7
15
|
NOTE_HASH_SUBTREE_HEIGHT,
|
|
8
|
-
|
|
16
|
+
NOTE_HASH_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
9
17
|
NULLIFIER_SUBTREE_HEIGHT,
|
|
10
|
-
|
|
18
|
+
NULLIFIER_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
11
19
|
NULLIFIER_TREE_HEIGHT,
|
|
12
|
-
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
13
20
|
PUBLIC_DATA_TREE_HEIGHT,
|
|
14
21
|
} from '@aztec/constants';
|
|
15
22
|
import { makeTuple } from '@aztec/foundation/array';
|
|
23
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
16
24
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
23
|
-
import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
|
|
25
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
26
|
+
import { type Bufferable, assertLength, toFriendlyJSON } from '@aztec/foundation/serialize';
|
|
27
|
+
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
28
|
+
import { getVkData } from '@aztec/noir-protocol-circuits-types/server/vks';
|
|
29
|
+
import { getVKIndex, getVKSiblingPath } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
24
30
|
import { computeFeePayerBalanceLeafSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
25
|
-
import { PublicDataHint } from '@aztec/stdlib/avm';
|
|
26
31
|
import { Body } from '@aztec/stdlib/block';
|
|
27
|
-
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
28
|
-
import {
|
|
29
|
-
import
|
|
32
|
+
import type { MerkleTreeWriteOperations, PublicInputsAndRecursiveProof } from '@aztec/stdlib/interfaces/server';
|
|
33
|
+
import { ContractClassLogFields } from '@aztec/stdlib/logs';
|
|
34
|
+
import { Proof, ProofData, RecursiveProof } from '@aztec/stdlib/proofs';
|
|
30
35
|
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
ConstantRollupData,
|
|
36
|
+
BlockConstantData,
|
|
37
|
+
BlockRollupPublicInputs,
|
|
34
38
|
PrivateBaseRollupHints,
|
|
35
|
-
PrivateBaseStateDiffHints,
|
|
36
39
|
PublicBaseRollupHints,
|
|
40
|
+
PublicChonkVerifierPrivateInputs,
|
|
41
|
+
TreeSnapshotDiffHints,
|
|
37
42
|
} from '@aztec/stdlib/rollup';
|
|
38
43
|
import {
|
|
39
44
|
AppendOnlyTreeSnapshot,
|
|
40
45
|
MerkleTreeId,
|
|
41
46
|
NullifierLeafPreimage,
|
|
42
|
-
PublicDataTreeLeaf,
|
|
43
47
|
PublicDataTreeLeafPreimage,
|
|
44
48
|
getTreeHeight,
|
|
45
49
|
} from '@aztec/stdlib/trees';
|
|
46
50
|
import {
|
|
47
51
|
BlockHeader,
|
|
48
|
-
|
|
49
|
-
type GlobalVariables,
|
|
52
|
+
GlobalVariables,
|
|
50
53
|
PartialStateReference,
|
|
51
54
|
type ProcessedTx,
|
|
52
55
|
StateReference,
|
|
53
|
-
|
|
56
|
+
Tx,
|
|
54
57
|
} from '@aztec/stdlib/tx';
|
|
58
|
+
import { VkData } from '@aztec/stdlib/vks';
|
|
55
59
|
import { Attributes, type Span, runInSpan } from '@aztec/telemetry-client';
|
|
56
60
|
import type { MerkleTreeReadOperations } from '@aztec/world-state';
|
|
57
61
|
|
|
58
|
-
import { inspect } from 'util';
|
|
59
|
-
|
|
60
62
|
/**
|
|
61
63
|
* Type representing the names of the trees for the base rollup.
|
|
62
64
|
*/
|
|
@@ -67,242 +69,236 @@ type BaseTreeNames = 'NoteHashTree' | 'ContractTree' | 'NullifierTree' | 'Public
|
|
|
67
69
|
export type TreeNames = BaseTreeNames | 'L1ToL2MessageTree' | 'Archive';
|
|
68
70
|
|
|
69
71
|
// Builds the hints for base rollup. Updating the contract, nullifier, and data trees in the process.
|
|
70
|
-
export const
|
|
72
|
+
export const insertSideEffectsAndBuildBaseRollupHints = runInSpan(
|
|
71
73
|
'BlockBuilderHelpers',
|
|
72
74
|
'buildBaseRollupHints',
|
|
73
75
|
async (
|
|
74
76
|
span: Span,
|
|
75
77
|
tx: ProcessedTx,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
lastArchive: AppendOnlyTreeSnapshot,
|
|
79
|
+
newL1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
78
80
|
startSpongeBlob: SpongeBlob,
|
|
81
|
+
proverId: Fr,
|
|
82
|
+
db: MerkleTreeWriteOperations,
|
|
79
83
|
) => {
|
|
80
84
|
span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
|
|
81
85
|
// Get trees info before any changes hit
|
|
82
|
-
const constants = await getConstantRollupData(globalVariables, db);
|
|
83
86
|
const start = new PartialStateReference(
|
|
84
87
|
await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
|
|
85
88
|
await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
|
|
86
89
|
await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
|
|
87
90
|
);
|
|
88
|
-
// Get the subtree sibling paths for the circuit
|
|
89
|
-
const noteHashSubtreeSiblingPathArray = await getSubtreeSiblingPath(
|
|
90
|
-
MerkleTreeId.NOTE_HASH_TREE,
|
|
91
|
-
NOTE_HASH_SUBTREE_HEIGHT,
|
|
92
|
-
db,
|
|
93
|
-
);
|
|
94
91
|
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
// Get the note hash subtree root sibling path for insertion.
|
|
93
|
+
const noteHashSubtreeRootSiblingPath = assertLength(
|
|
94
|
+
await getSubtreeSiblingPath(MerkleTreeId.NOTE_HASH_TREE, NOTE_HASH_SUBTREE_HEIGHT, db),
|
|
95
|
+
NOTE_HASH_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
97
96
|
);
|
|
98
97
|
|
|
99
|
-
|
|
100
|
-
// that will be used by the next iteration of the base rollup circuit, skipping the empty ones
|
|
101
|
-
const noteHashes = padArrayEnd(tx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX);
|
|
102
|
-
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashes);
|
|
103
|
-
|
|
104
|
-
// Create data hint for reading fee payer initial balance in Fee Juice
|
|
105
|
-
const leafSlot = await computeFeePayerBalanceLeafSlot(tx.data.feePayer);
|
|
106
|
-
const feePayerFeeJuiceBalanceReadHint = await getPublicDataHint(db, leafSlot.toBigInt());
|
|
107
|
-
|
|
108
|
-
// The read witnesses for a given TX should be generated before the writes of the same TX are applied.
|
|
109
|
-
// All reads that refer to writes in the same tx are transient and can be simplified out.
|
|
110
|
-
const txPublicDataUpdateRequestInfo = await processPublicDataUpdateRequests(tx, db);
|
|
111
|
-
|
|
112
|
-
// Update the nullifier tree, capturing the low nullifier info for each individual operation
|
|
113
|
-
const {
|
|
114
|
-
lowLeavesWitnessData: nullifierWitnessLeaves,
|
|
115
|
-
newSubtreeSiblingPath: nullifiersSubtreeSiblingPath,
|
|
116
|
-
sortedNewLeaves: sortednullifiers,
|
|
117
|
-
sortedNewLeavesIndexes,
|
|
118
|
-
} = await db.batchInsert(
|
|
119
|
-
MerkleTreeId.NULLIFIER_TREE,
|
|
120
|
-
padArrayEnd(tx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()),
|
|
121
|
-
NULLIFIER_SUBTREE_HEIGHT,
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
if (nullifierWitnessLeaves === undefined) {
|
|
125
|
-
throw new Error(`Could not craft nullifier batch insertion proofs`);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Extract witness objects from returned data
|
|
129
|
-
const nullifierPredecessorMembershipWitnessesWithoutPadding: MembershipWitness<typeof NULLIFIER_TREE_HEIGHT>[] =
|
|
130
|
-
nullifierWitnessLeaves.map(l =>
|
|
131
|
-
MembershipWitness.fromBufferArray(l.index, assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT)),
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
const nullifierSubtreeSiblingPathArray = nullifiersSubtreeSiblingPath.toFields();
|
|
135
|
-
|
|
136
|
-
const nullifierSubtreeSiblingPath = makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, i =>
|
|
137
|
-
i < nullifierSubtreeSiblingPathArray.length ? nullifierSubtreeSiblingPathArray[i] : Fr.ZERO,
|
|
138
|
-
);
|
|
98
|
+
const { nullifierInsertionResult, publicDataInsertionResult } = await insertSideEffects(tx, db);
|
|
139
99
|
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
100
|
+
const blockHash = await tx.data.constants.anchorBlockHeader.hash();
|
|
101
|
+
const anchorBlockArchiveSiblingPath = (
|
|
102
|
+
await getMembershipWitnessFor(blockHash, MerkleTreeId.ARCHIVE, ARCHIVE_HEIGHT, db)
|
|
103
|
+
).siblingPath;
|
|
143
104
|
|
|
144
|
-
const
|
|
105
|
+
const contractClassLogsFields = makeTuple(
|
|
145
106
|
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
146
|
-
i => tx.txEffect.contractClassLogs[i]?.
|
|
107
|
+
i => tx.txEffect.contractClassLogs[i]?.fields || ContractClassLogFields.empty(),
|
|
147
108
|
);
|
|
148
109
|
|
|
149
110
|
if (tx.avmProvingRequest) {
|
|
150
|
-
const blockHash = await tx.constants.historicalHeader.hash();
|
|
151
|
-
const archiveRootMembershipWitness = await getMembershipWitnessFor(
|
|
152
|
-
blockHash,
|
|
153
|
-
MerkleTreeId.ARCHIVE,
|
|
154
|
-
ARCHIVE_HEIGHT,
|
|
155
|
-
db,
|
|
156
|
-
);
|
|
157
|
-
|
|
158
111
|
return PublicBaseRollupHints.from({
|
|
159
|
-
startSpongeBlob
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
112
|
+
startSpongeBlob,
|
|
113
|
+
lastArchive,
|
|
114
|
+
anchorBlockArchiveSiblingPath,
|
|
115
|
+
contractClassLogsFields,
|
|
163
116
|
});
|
|
164
117
|
} else {
|
|
165
|
-
if (
|
|
166
|
-
txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses.length > 1 ||
|
|
167
|
-
txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages.length > 1 ||
|
|
168
|
-
txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths.length > 1
|
|
169
|
-
) {
|
|
118
|
+
if (tx.txEffect.publicDataWrites.length > 1) {
|
|
170
119
|
throw new Error(`More than one public data write in a private only tx`);
|
|
171
120
|
}
|
|
172
121
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
122
|
+
// Get hints for reading fee payer's balance in the public data tree.
|
|
123
|
+
const feePayerBalanceLeafWitnessData = publicDataInsertionResult.lowLeavesWitnessData[0];
|
|
124
|
+
const feePayerBalanceMembershipWitness = MembershipWitness.fromBufferArray<typeof PUBLIC_DATA_TREE_HEIGHT>(
|
|
125
|
+
feePayerBalanceLeafWitnessData.index,
|
|
126
|
+
assertLength(feePayerBalanceLeafWitnessData.siblingPath.toBufferArray(), PUBLIC_DATA_TREE_HEIGHT),
|
|
127
|
+
);
|
|
128
|
+
const feePayerBalanceLeafPreimage = feePayerBalanceLeafWitnessData.leafPreimage as PublicDataTreeLeafPreimage;
|
|
129
|
+
const leafSlot = await computeFeePayerBalanceLeafSlot(tx.data.feePayer);
|
|
130
|
+
if (!leafSlot.equals(feePayerBalanceLeafPreimage.leaf.slot)) {
|
|
131
|
+
throw new Error(`Cannot find the public data tree leaf for the fee payer's balance`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Get hints for inserting the nullifiers.
|
|
135
|
+
const nullifierLowLeavesWitnessData = nullifierInsertionResult.lowLeavesWitnessData!;
|
|
136
|
+
const nullifierPredecessorPreimages = padArrayEnd(
|
|
137
|
+
nullifierLowLeavesWitnessData.map(l => l.leafPreimage as NullifierLeafPreimage),
|
|
138
|
+
NullifierLeafPreimage.empty(),
|
|
139
|
+
MAX_NULLIFIERS_PER_TX,
|
|
140
|
+
);
|
|
141
|
+
const nullifierPredecessorMembershipWitnesses = padArrayEnd(
|
|
142
|
+
nullifierLowLeavesWitnessData.map(l =>
|
|
143
|
+
MembershipWitness.fromBufferArray<typeof NULLIFIER_TREE_HEIGHT>(
|
|
144
|
+
l.index,
|
|
145
|
+
assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT),
|
|
146
|
+
),
|
|
192
147
|
),
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
148
|
+
makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
|
|
149
|
+
MAX_NULLIFIERS_PER_TX,
|
|
150
|
+
);
|
|
151
|
+
const sortedNullifiers = assertLength(
|
|
152
|
+
nullifierInsertionResult.sortedNewLeaves.map(n => Fr.fromBuffer(n)),
|
|
153
|
+
MAX_NULLIFIERS_PER_TX,
|
|
154
|
+
);
|
|
155
|
+
const sortedNullifierIndexes = assertLength(
|
|
156
|
+
nullifierInsertionResult.sortedNewLeavesIndexes,
|
|
157
|
+
MAX_NULLIFIERS_PER_TX,
|
|
158
|
+
);
|
|
159
|
+
const nullifierSubtreeRootSiblingPath = assertLength(
|
|
160
|
+
nullifierInsertionResult.newSubtreeSiblingPath.toFields(),
|
|
161
|
+
NULLIFIER_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const treeSnapshotDiffHints = TreeSnapshotDiffHints.from({
|
|
165
|
+
noteHashSubtreeRootSiblingPath,
|
|
166
|
+
nullifierPredecessorPreimages,
|
|
167
|
+
nullifierPredecessorMembershipWitnesses,
|
|
168
|
+
sortedNullifiers,
|
|
169
|
+
sortedNullifierIndexes,
|
|
170
|
+
nullifierSubtreeRootSiblingPath,
|
|
171
|
+
feePayerBalanceMembershipWitness,
|
|
200
172
|
});
|
|
201
173
|
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
174
|
+
const constants = BlockConstantData.from({
|
|
175
|
+
lastArchive,
|
|
176
|
+
l1ToL2TreeSnapshot: newL1ToL2MessageTreeSnapshot,
|
|
177
|
+
vkTreeRoot: tx.data.constants.vkTreeRoot,
|
|
178
|
+
protocolContractsHash: tx.data.constants.protocolContractsHash,
|
|
179
|
+
globalVariables: tx.globalVariables,
|
|
180
|
+
proverId,
|
|
181
|
+
});
|
|
209
182
|
|
|
210
183
|
return PrivateBaseRollupHints.from({
|
|
211
184
|
start,
|
|
212
|
-
startSpongeBlob
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
185
|
+
startSpongeBlob,
|
|
186
|
+
treeSnapshotDiffHints,
|
|
187
|
+
feePayerBalanceLeafPreimage,
|
|
188
|
+
anchorBlockArchiveSiblingPath,
|
|
189
|
+
contractClassLogsFields,
|
|
217
190
|
constants,
|
|
218
191
|
});
|
|
219
192
|
}
|
|
220
193
|
},
|
|
221
194
|
);
|
|
222
195
|
|
|
223
|
-
export
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
196
|
+
export const insertSideEffects = runInSpan(
|
|
197
|
+
'BlockBuilderHelpers',
|
|
198
|
+
'buildBaseRollupHints',
|
|
199
|
+
async (span: Span, tx: ProcessedTx, db: MerkleTreeWriteOperations) => {
|
|
200
|
+
span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
|
|
228
201
|
|
|
229
|
-
|
|
230
|
-
|
|
202
|
+
// Insert the note hashes. Padded with zeros to the max number of note hashes per tx.
|
|
203
|
+
const noteHashes = padArrayEnd(tx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX);
|
|
204
|
+
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashes);
|
|
231
205
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
206
|
+
// Insert the nullifiers. Padded with zeros to the max number of nullifiers per tx.
|
|
207
|
+
// Capturing the low nullifier info for each individual operation.
|
|
208
|
+
const nullifierInsertionResult = await db.batchInsert(
|
|
209
|
+
MerkleTreeId.NULLIFIER_TREE,
|
|
210
|
+
padArrayEnd(tx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()),
|
|
211
|
+
NULLIFIER_SUBTREE_HEIGHT,
|
|
212
|
+
);
|
|
213
|
+
if (nullifierInsertionResult.lowLeavesWitnessData === undefined) {
|
|
214
|
+
throw new Error(`Failed to batch insert nullifiers.`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (tx.txEffect.publicDataWrites.some(write => write.isEmpty())) {
|
|
218
|
+
throw new Error(`Empty public data write in tx: ${toFriendlyJSON(tx)}.`);
|
|
219
|
+
}
|
|
220
|
+
// Insert the public data writes sequentially. No need to pad them to the max array size.
|
|
221
|
+
// Capturing the low leaf info for each individual operation.
|
|
222
|
+
const publicDataInsertionResult = await db.sequentialInsert(
|
|
223
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
224
|
+
tx.txEffect.publicDataWrites.map(write => write.toBuffer()),
|
|
225
|
+
);
|
|
236
226
|
|
|
237
|
-
|
|
238
|
-
|
|
227
|
+
return {
|
|
228
|
+
nullifierInsertionResult,
|
|
229
|
+
publicDataInsertionResult,
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
export function getChonkProofFromTx(tx: Tx | ProcessedTx) {
|
|
235
|
+
const publicInputs = tx.data.publicInputs().toFields();
|
|
236
|
+
|
|
237
|
+
const binaryProof = new Proof(
|
|
238
|
+
Buffer.concat(tx.chonkProof.attachPublicInputs(publicInputs).fieldsWithPublicInputs.map(field => field.toBuffer())),
|
|
239
|
+
publicInputs.length,
|
|
240
|
+
);
|
|
241
|
+
return new RecursiveProof(tx.chonkProof.fields, binaryProof, true, CHONK_PROOF_LENGTH);
|
|
242
|
+
}
|
|
239
243
|
|
|
240
|
-
|
|
244
|
+
export function getPublicChonkVerifierPrivateInputsFromTx(tx: Tx | ProcessedTx, proverId: Fr) {
|
|
245
|
+
const proofData = new ProofData(
|
|
246
|
+
tx.data.toPrivateToPublicKernelCircuitPublicInputs(),
|
|
247
|
+
getChonkProofFromTx(tx),
|
|
248
|
+
getVkData('HidingKernelToPublic'),
|
|
249
|
+
);
|
|
250
|
+
return new PublicChonkVerifierPrivateInputs(proofData, proverId);
|
|
241
251
|
}
|
|
242
252
|
|
|
243
|
-
|
|
253
|
+
// Build "hints" as the private inputs for the checkpoint root rollup circuit.
|
|
254
|
+
// The `blobCommitments` will be accumulated and checked in the root rollup against the `finalBlobChallenges`.
|
|
255
|
+
// The `blobsHash` will be validated on L1 against the submitted blob data.
|
|
256
|
+
export const buildBlobHints = (blobFields: Fr[]) => {
|
|
257
|
+
const blobs = getBlobsPerL1Block(blobFields);
|
|
258
|
+
const blobCommitments = getBlobCommitmentsFromBlobs(blobs);
|
|
259
|
+
const blobsHash = computeBlobsHashFromBlobs(blobs);
|
|
260
|
+
return { blobCommitments, blobs, blobsHash };
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
export const buildFinalBlobChallenges = async (blobFieldsPerCheckpoint: Fr[][]) => {
|
|
264
|
+
return await BatchedBlobAccumulator.precomputeBatchedBlobChallenges(blobFieldsPerCheckpoint);
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
export const accumulateBlobs = runInSpan(
|
|
244
268
|
'BlockBuilderHelpers',
|
|
245
|
-
'
|
|
246
|
-
async (_span: Span,
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
const blobCommitments = blobs.map(b => b.commitmentToFields());
|
|
250
|
-
const blobsHash = new Fr(getBlobsHashFromBlobs(blobs));
|
|
251
|
-
return { blobFields, blobCommitments, blobs, blobsHash };
|
|
269
|
+
'accumulateBlobs',
|
|
270
|
+
async (_span: Span, blobFields: Fr[], startBlobAccumulator: BatchedBlobAccumulator) => {
|
|
271
|
+
const endBlobAccumulator = await startBlobAccumulator.accumulateFields(blobFields);
|
|
272
|
+
return endBlobAccumulator;
|
|
252
273
|
},
|
|
253
274
|
);
|
|
254
275
|
|
|
255
276
|
export const buildHeaderFromCircuitOutputs = runInSpan(
|
|
256
277
|
'BlockBuilderHelpers',
|
|
257
278
|
'buildHeaderFromCircuitOutputs',
|
|
258
|
-
async (
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
279
|
+
async (_span, blockRootRollupOutput: BlockRollupPublicInputs) => {
|
|
280
|
+
const constants = blockRootRollupOutput.constants;
|
|
281
|
+
const globalVariables = GlobalVariables.from({
|
|
282
|
+
chainId: constants.chainId,
|
|
283
|
+
version: constants.version,
|
|
284
|
+
blockNumber: BlockNumber(blockRootRollupOutput.previousArchive.nextAvailableLeafIndex),
|
|
285
|
+
timestamp: blockRootRollupOutput.endTimestamp,
|
|
286
|
+
slotNumber: constants.slotNumber,
|
|
287
|
+
coinbase: constants.coinbase,
|
|
288
|
+
feeRecipient: constants.feeRecipient,
|
|
289
|
+
gasFees: constants.gasFees,
|
|
290
|
+
});
|
|
269
291
|
|
|
270
|
-
const
|
|
271
|
-
const numTxs = previousRollupData.reduce((sum, d) => sum + d.numTxs, 0);
|
|
272
|
-
const outHash =
|
|
273
|
-
previousRollupData.length === 0
|
|
274
|
-
? Fr.ZERO.toBuffer()
|
|
275
|
-
: previousRollupData.length === 1
|
|
276
|
-
? previousRollupData[0].outHash.toBuffer()
|
|
277
|
-
: sha256Trunc(
|
|
278
|
-
Buffer.concat([previousRollupData[0].outHash.toBuffer(), previousRollupData[1].outHash.toBuffer()]),
|
|
279
|
-
);
|
|
280
|
-
const contentCommitment = new ContentCommitment(
|
|
281
|
-
new Fr(numTxs),
|
|
282
|
-
blobsHash,
|
|
283
|
-
parityPublicInputs.shaRoot.toBuffer(),
|
|
284
|
-
outHash,
|
|
285
|
-
);
|
|
292
|
+
const spongeBlobHash = await blockRootRollupOutput.endSpongeBlob.clone().squeeze();
|
|
286
293
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
accumulatedFees,
|
|
295
|
-
accumulatedManaUsed,
|
|
294
|
+
return new BlockHeader(
|
|
295
|
+
blockRootRollupOutput.previousArchive,
|
|
296
|
+
blockRootRollupOutput.endState,
|
|
297
|
+
spongeBlobHash,
|
|
298
|
+
globalVariables,
|
|
299
|
+
blockRootRollupOutput.accumulatedFees,
|
|
300
|
+
blockRootRollupOutput.accumulatedManaUsed,
|
|
296
301
|
);
|
|
297
|
-
if (!(await header.hash()).equals(rootRollupOutputs.endBlockHash)) {
|
|
298
|
-
logger?.error(
|
|
299
|
-
`Block header mismatch when building header from circuit outputs.` +
|
|
300
|
-
`\n\nHeader: ${inspect(header)}` +
|
|
301
|
-
`\n\nCircuit: ${toFriendlyJSON(rootRollupOutputs)}`,
|
|
302
|
-
);
|
|
303
|
-
throw new Error(`Block header mismatch when building from circuit outputs`);
|
|
304
|
-
}
|
|
305
|
-
return header;
|
|
306
302
|
},
|
|
307
303
|
);
|
|
308
304
|
|
|
@@ -312,111 +308,72 @@ export const buildHeaderAndBodyFromTxs = runInSpan(
|
|
|
312
308
|
async (
|
|
313
309
|
span,
|
|
314
310
|
txs: ProcessedTx[],
|
|
311
|
+
lastArchive: AppendOnlyTreeSnapshot,
|
|
312
|
+
endState: StateReference,
|
|
315
313
|
globalVariables: GlobalVariables,
|
|
316
|
-
|
|
317
|
-
|
|
314
|
+
startSpongeBlob: SpongeBlob,
|
|
315
|
+
isFirstBlock: boolean,
|
|
318
316
|
) => {
|
|
319
|
-
span.setAttribute(Attributes.BLOCK_NUMBER, globalVariables.blockNumber
|
|
320
|
-
const stateReference = new StateReference(
|
|
321
|
-
await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db),
|
|
322
|
-
new PartialStateReference(
|
|
323
|
-
await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
|
|
324
|
-
await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
|
|
325
|
-
await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
|
|
326
|
-
),
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
const previousArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
317
|
+
span.setAttribute(Attributes.BLOCK_NUMBER, globalVariables.blockNumber);
|
|
330
318
|
|
|
331
319
|
const txEffects = txs.map(tx => tx.txEffect);
|
|
332
320
|
const body = new Body(txEffects);
|
|
333
321
|
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
numTxs === 0
|
|
337
|
-
? Fr.ZERO.toBuffer()
|
|
338
|
-
: numTxs === 1
|
|
339
|
-
? body.txEffects[0].txOutHash()
|
|
340
|
-
: computeUnbalancedMerkleRoot(
|
|
341
|
-
body.txEffects.map(tx => tx.txOutHash()),
|
|
342
|
-
TxEffect.empty().txOutHash(),
|
|
343
|
-
);
|
|
322
|
+
const totalFees = txEffects.reduce((acc, tx) => acc.add(tx.transactionFee), Fr.ZERO);
|
|
323
|
+
const totalManaUsed = txs.reduce((acc, tx) => acc.add(new Fr(tx.gasUsed.billedGas.l2Gas)), Fr.ZERO);
|
|
344
324
|
|
|
345
|
-
|
|
346
|
-
const hasher = (left: Buffer, right: Buffer) => Promise.resolve(sha256Trunc(Buffer.concat([left, right])));
|
|
347
|
-
const parityHeight = Math.ceil(Math.log2(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP));
|
|
348
|
-
const parityCalculator = await MerkleTreeCalculator.create(parityHeight, Fr.ZERO.toBuffer(), hasher);
|
|
349
|
-
const parityShaRoot = await parityCalculator.computeTreeRoot(l1ToL2Messages.map(msg => msg.toBuffer()));
|
|
350
|
-
const blobsHash = getBlobsHashFromBlobs(await Blob.getBlobs(body.toBlobFields()));
|
|
325
|
+
const { l1ToL2MessageTree, partial } = endState;
|
|
351
326
|
|
|
352
|
-
const
|
|
327
|
+
const blockBlobFields = encodeBlockBlobData({
|
|
328
|
+
blockEndMarker: {
|
|
329
|
+
timestamp: globalVariables.timestamp,
|
|
330
|
+
blockNumber: globalVariables.blockNumber,
|
|
331
|
+
numTxs: txs.length,
|
|
332
|
+
},
|
|
333
|
+
blockEndStateField: {
|
|
334
|
+
l1ToL2MessageNextAvailableLeafIndex: l1ToL2MessageTree.nextAvailableLeafIndex,
|
|
335
|
+
noteHashNextAvailableLeafIndex: partial.noteHashTree.nextAvailableLeafIndex,
|
|
336
|
+
nullifierNextAvailableLeafIndex: partial.nullifierTree.nextAvailableLeafIndex,
|
|
337
|
+
publicDataNextAvailableLeafIndex: partial.publicDataTree.nextAvailableLeafIndex,
|
|
338
|
+
totalManaUsed: totalManaUsed.toBigInt(),
|
|
339
|
+
},
|
|
340
|
+
lastArchiveRoot: lastArchive.root,
|
|
341
|
+
noteHashRoot: partial.noteHashTree.root,
|
|
342
|
+
nullifierRoot: partial.nullifierTree.root,
|
|
343
|
+
publicDataRoot: partial.publicDataTree.root,
|
|
344
|
+
l1ToL2MessageRoot: isFirstBlock ? l1ToL2MessageTree.root : undefined,
|
|
345
|
+
txs: body.toTxBlobData(),
|
|
346
|
+
});
|
|
353
347
|
|
|
354
|
-
const
|
|
355
|
-
|
|
348
|
+
const endSpongeBlob = startSpongeBlob.clone();
|
|
349
|
+
await endSpongeBlob.absorb(blockBlobFields);
|
|
350
|
+
const spongeBlobHash = await endSpongeBlob.squeeze();
|
|
356
351
|
|
|
357
|
-
const header =
|
|
352
|
+
const header = BlockHeader.from({
|
|
353
|
+
lastArchive,
|
|
354
|
+
state: endState,
|
|
355
|
+
spongeBlobHash,
|
|
356
|
+
globalVariables,
|
|
357
|
+
totalFees,
|
|
358
|
+
totalManaUsed,
|
|
359
|
+
});
|
|
358
360
|
|
|
359
|
-
return { header, body };
|
|
361
|
+
return { header, body, blockBlobFields };
|
|
360
362
|
},
|
|
361
363
|
);
|
|
362
364
|
|
|
363
|
-
export function
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
// Validate that the roots of all local trees match the output of the root circuit simulation
|
|
369
|
-
export async function validateBlockRootOutput(
|
|
370
|
-
blockRootOutput: BlockRootOrBlockMergePublicInputs,
|
|
371
|
-
blockHeader: BlockHeader,
|
|
372
|
-
db: MerkleTreeReadOperations,
|
|
373
|
-
) {
|
|
374
|
-
await Promise.all([
|
|
375
|
-
validateState(blockHeader.state, db),
|
|
376
|
-
validateSimulatedTree(await getTreeSnapshot(MerkleTreeId.ARCHIVE, db), blockRootOutput.newArchive, 'Archive'),
|
|
377
|
-
]);
|
|
365
|
+
export async function getLastSiblingPath<TID extends MerkleTreeId>(treeId: TID, db: MerkleTreeReadOperations) {
|
|
366
|
+
const { size } = await db.getTreeInfo(treeId);
|
|
367
|
+
const path = await db.getSiblingPath(treeId, size - 1n);
|
|
368
|
+
return padArrayEnd(path.toFields(), Fr.ZERO, getTreeHeight(treeId));
|
|
378
369
|
}
|
|
379
370
|
|
|
380
|
-
export const validateState = runInSpan(
|
|
381
|
-
'BlockBuilderHelpers',
|
|
382
|
-
'validateState',
|
|
383
|
-
async (_span, state: StateReference, db: MerkleTreeReadOperations) => {
|
|
384
|
-
const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(
|
|
385
|
-
async (id: MerkleTreeId) => {
|
|
386
|
-
return { key: id, value: await getTreeSnapshot(id, db) };
|
|
387
|
-
},
|
|
388
|
-
);
|
|
389
|
-
const snapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot> = new Map(
|
|
390
|
-
(await Promise.all(promises)).map(obj => [obj.key, obj.value]),
|
|
391
|
-
);
|
|
392
|
-
validatePartialState(state.partial, snapshots);
|
|
393
|
-
validateSimulatedTree(
|
|
394
|
-
await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db),
|
|
395
|
-
state.l1ToL2MessageTree,
|
|
396
|
-
'L1ToL2MessageTree',
|
|
397
|
-
);
|
|
398
|
-
},
|
|
399
|
-
);
|
|
400
|
-
|
|
401
371
|
export async function getRootTreeSiblingPath<TID extends MerkleTreeId>(treeId: TID, db: MerkleTreeReadOperations) {
|
|
402
372
|
const { size } = await db.getTreeInfo(treeId);
|
|
403
373
|
const path = await db.getSiblingPath(treeId, size);
|
|
404
374
|
return padArrayEnd(path.toFields(), Fr.ZERO, getTreeHeight(treeId));
|
|
405
375
|
}
|
|
406
376
|
|
|
407
|
-
export const getConstantRollupData = runInSpan(
|
|
408
|
-
'BlockBuilderHelpers',
|
|
409
|
-
'getConstantRollupData',
|
|
410
|
-
async (_span, globalVariables: GlobalVariables, db: MerkleTreeReadOperations): Promise<ConstantRollupData> => {
|
|
411
|
-
return ConstantRollupData.from({
|
|
412
|
-
vkTreeRoot: getVKTreeRoot(),
|
|
413
|
-
protocolContractTreeRoot,
|
|
414
|
-
lastArchive: await getTreeSnapshot(MerkleTreeId.ARCHIVE, db),
|
|
415
|
-
globalVariables,
|
|
416
|
-
});
|
|
417
|
-
},
|
|
418
|
-
);
|
|
419
|
-
|
|
420
377
|
export async function getTreeSnapshot(id: MerkleTreeId, db: MerkleTreeReadOperations): Promise<AppendOnlyTreeSnapshot> {
|
|
421
378
|
const treeInfo = await db.getTreeInfo(id);
|
|
422
379
|
return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size));
|
|
@@ -430,48 +387,6 @@ export function makeEmptyMembershipWitness<N extends number>(height: N) {
|
|
|
430
387
|
);
|
|
431
388
|
}
|
|
432
389
|
|
|
433
|
-
const processPublicDataUpdateRequests = runInSpan(
|
|
434
|
-
'BlockBuilderHelpers',
|
|
435
|
-
'processPublicDataUpdateRequests',
|
|
436
|
-
async (span, tx: ProcessedTx, db: MerkleTreeWriteOperations) => {
|
|
437
|
-
span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
|
|
438
|
-
const allPublicDataWrites = tx.txEffect.publicDataWrites.map(
|
|
439
|
-
({ leafSlot, value }) => new PublicDataTreeLeaf(leafSlot, value),
|
|
440
|
-
);
|
|
441
|
-
|
|
442
|
-
const { lowLeavesWitnessData, insertionWitnessData } = await db.sequentialInsert(
|
|
443
|
-
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
444
|
-
allPublicDataWrites.map(write => {
|
|
445
|
-
if (write.isEmpty()) {
|
|
446
|
-
throw new Error(`Empty public data write in tx: ${toFriendlyJSON(tx)}`);
|
|
447
|
-
}
|
|
448
|
-
return write.toBuffer();
|
|
449
|
-
}),
|
|
450
|
-
);
|
|
451
|
-
|
|
452
|
-
const lowPublicDataWritesPreimages = lowLeavesWitnessData.map(
|
|
453
|
-
lowLeafWitness => lowLeafWitness.leafPreimage as PublicDataTreeLeafPreimage,
|
|
454
|
-
);
|
|
455
|
-
const lowPublicDataWritesMembershipWitnesses = lowLeavesWitnessData.map(lowLeafWitness =>
|
|
456
|
-
MembershipWitness.fromBufferArray<typeof PUBLIC_DATA_TREE_HEIGHT>(
|
|
457
|
-
lowLeafWitness.index,
|
|
458
|
-
assertLength(lowLeafWitness.siblingPath.toBufferArray(), PUBLIC_DATA_TREE_HEIGHT),
|
|
459
|
-
),
|
|
460
|
-
);
|
|
461
|
-
const publicDataWritesSiblingPaths = insertionWitnessData.map(w => {
|
|
462
|
-
const insertionSiblingPath = w.siblingPath.toFields();
|
|
463
|
-
assertLength(insertionSiblingPath, PUBLIC_DATA_TREE_HEIGHT);
|
|
464
|
-
return insertionSiblingPath as Tuple<Fr, typeof PUBLIC_DATA_TREE_HEIGHT>;
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
return {
|
|
468
|
-
lowPublicDataWritesPreimages,
|
|
469
|
-
lowPublicDataWritesMembershipWitnesses,
|
|
470
|
-
publicDataWritesSiblingPaths,
|
|
471
|
-
};
|
|
472
|
-
},
|
|
473
|
-
);
|
|
474
|
-
|
|
475
390
|
export async function getSubtreeSiblingPath(
|
|
476
391
|
treeId: MerkleTreeId,
|
|
477
392
|
subtreeHeight: number,
|
|
@@ -537,17 +452,26 @@ function validateSimulatedTree(
|
|
|
537
452
|
}
|
|
538
453
|
|
|
539
454
|
export function validateTx(tx: ProcessedTx) {
|
|
540
|
-
const txHeader = tx.constants.
|
|
541
|
-
if (txHeader.state.l1ToL2MessageTree.
|
|
455
|
+
const txHeader = tx.data.constants.anchorBlockHeader;
|
|
456
|
+
if (txHeader.state.l1ToL2MessageTree.isEmpty()) {
|
|
542
457
|
throw new Error(`Empty L1 to L2 messages tree in tx: ${toFriendlyJSON(tx)}`);
|
|
543
458
|
}
|
|
544
|
-
if (txHeader.state.partial.noteHashTree.
|
|
459
|
+
if (txHeader.state.partial.noteHashTree.isEmpty()) {
|
|
545
460
|
throw new Error(`Empty note hash tree in tx: ${toFriendlyJSON(tx)}`);
|
|
546
461
|
}
|
|
547
|
-
if (txHeader.state.partial.nullifierTree.
|
|
462
|
+
if (txHeader.state.partial.nullifierTree.isEmpty()) {
|
|
548
463
|
throw new Error(`Empty nullifier tree in tx: ${toFriendlyJSON(tx)}`);
|
|
549
464
|
}
|
|
550
|
-
if (txHeader.state.partial.publicDataTree.
|
|
465
|
+
if (txHeader.state.partial.publicDataTree.isEmpty()) {
|
|
551
466
|
throw new Error(`Empty public data tree in tx: ${toFriendlyJSON(tx)}`);
|
|
552
467
|
}
|
|
553
468
|
}
|
|
469
|
+
|
|
470
|
+
export function toProofData<T extends Bufferable, PROOF_LENGTH extends number>(
|
|
471
|
+
{ inputs, proof, verificationKey }: PublicInputsAndRecursiveProof<T, PROOF_LENGTH>,
|
|
472
|
+
vkIndex?: number,
|
|
473
|
+
) {
|
|
474
|
+
const leafIndex = vkIndex || getVKIndex(verificationKey.keyAsFields);
|
|
475
|
+
const vkData = new VkData(verificationKey, leafIndex, getVKSiblingPath(leafIndex));
|
|
476
|
+
return new ProofData(inputs, proof, vkData);
|
|
477
|
+
}
|