@aztec/stdlib 3.0.0-nightly.20251114 → 3.0.0-nightly.20251115
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/avm/avm.d.ts +102 -8
- package/dest/avm/avm.d.ts.map +1 -1
- package/dest/avm/avm.js +43 -4
- package/dest/avm/public_data_write.d.ts +1 -1
- package/dest/avm/public_data_write.d.ts.map +1 -1
- package/dest/avm/revert_code.d.ts +2 -1
- package/dest/avm/revert_code.d.ts.map +1 -1
- package/dest/avm/revert_code.js +8 -8
- package/dest/block/body.d.ts +3 -6
- package/dest/block/body.d.ts.map +1 -1
- package/dest/block/body.js +6 -25
- package/dest/block/index.d.ts +1 -0
- package/dest/block/index.d.ts.map +1 -1
- package/dest/block/index.js +1 -0
- package/dest/block/l2_block.d.ts +5 -0
- package/dest/block/l2_block.d.ts.map +1 -1
- package/dest/block/l2_block.js +34 -4
- package/dest/block/l2_block_new.d.ts +97 -0
- package/dest/block/l2_block_new.d.ts.map +1 -0
- package/dest/block/l2_block_new.js +113 -0
- package/dest/checkpoint/checkpoint.d.ts +108 -0
- package/dest/checkpoint/checkpoint.d.ts.map +1 -0
- package/dest/checkpoint/checkpoint.js +39 -0
- package/dest/checkpoint/index.d.ts +1 -1
- package/dest/checkpoint/index.d.ts.map +1 -1
- package/dest/checkpoint/index.js +1 -1
- package/dest/logs/private_log.d.ts +1 -1
- package/dest/logs/private_log.d.ts.map +1 -1
- package/dest/logs/private_log.js +2 -5
- package/dest/messaging/in_hash.d.ts +4 -0
- package/dest/messaging/in_hash.d.ts.map +1 -0
- package/dest/messaging/in_hash.js +15 -0
- package/dest/messaging/index.d.ts +2 -0
- package/dest/messaging/index.d.ts.map +1 -1
- package/dest/messaging/index.js +2 -0
- package/dest/messaging/out_hash.d.ts +5 -0
- package/dest/messaging/out_hash.d.ts.map +1 -0
- package/dest/messaging/out_hash.js +28 -0
- package/dest/rollup/checkpoint_constant_data.d.ts +16 -0
- package/dest/rollup/checkpoint_constant_data.d.ts.map +1 -1
- package/dest/rollup/checkpoint_constant_data.js +17 -0
- package/dest/tests/factories.d.ts +17 -21
- package/dest/tests/factories.d.ts.map +1 -1
- package/dest/tests/factories.js +14 -111
- package/dest/tests/mocks.d.ts +17 -1
- package/dest/tests/mocks.d.ts.map +1 -1
- package/dest/tests/mocks.js +108 -4
- package/dest/tx/partial_state_reference.d.ts +3 -0
- package/dest/tx/partial_state_reference.d.ts.map +1 -1
- package/dest/tx/partial_state_reference.js +10 -0
- package/dest/tx/state_reference.d.ts +3 -0
- package/dest/tx/state_reference.d.ts.map +1 -1
- package/dest/tx/state_reference.js +9 -0
- package/dest/tx/tx_effect.d.ts +9 -6
- package/dest/tx/tx_effect.d.ts.map +1 -1
- package/dest/tx/tx_effect.js +53 -57
- package/package.json +8 -8
- package/src/avm/avm.ts +48 -10
- package/src/avm/public_data_write.ts +1 -1
- package/src/avm/revert_code.ts +9 -8
- package/src/block/body.ts +7 -32
- package/src/block/index.ts +1 -0
- package/src/block/l2_block.ts +33 -2
- package/src/block/l2_block_new.ts +143 -0
- package/src/checkpoint/checkpoint.ts +46 -0
- package/src/checkpoint/index.ts +1 -1
- package/src/logs/private_log.ts +2 -3
- package/src/messaging/in_hash.ts +15 -0
- package/src/messaging/index.ts +2 -0
- package/src/messaging/out_hash.ts +36 -0
- package/src/rollup/checkpoint_constant_data.ts +20 -0
- package/src/tests/factories.ts +91 -193
- package/src/tests/mocks.ts +196 -4
- package/src/tx/partial_state_reference.ts +9 -0
- package/src/tx/state_reference.ts +9 -0
- package/src/tx/tx_effect.ts +61 -67
- package/dest/checkpoint/checkpoint_body.d.ts +0 -4
- package/dest/checkpoint/checkpoint_body.d.ts.map +0 -1
- package/dest/checkpoint/checkpoint_body.js +0 -9
- package/src/checkpoint/checkpoint_body.ts +0 -10
package/dest/tx/tx_effect.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { decodeTxBlobData, encodeTxBlobData, getNumTxBlobFields } from '@aztec/blob-lib/encoding';
|
|
2
2
|
import { MAX_CONTRACT_CLASS_LOGS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_LOGS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX } from '@aztec/constants';
|
|
3
3
|
import { makeTuple, makeTupleAsync } from '@aztec/foundation/array';
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { schemas } from '@aztec/foundation/schemas';
|
|
6
|
-
import { BufferReader,
|
|
6
|
+
import { BufferReader, serializeArrayOfBufferableToVector, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
7
7
|
import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
|
|
8
|
-
import { computeUnbalancedMerkleTreeRoot } from '@aztec/foundation/trees';
|
|
9
8
|
import { inspect } from 'util';
|
|
10
9
|
import { z } from 'zod';
|
|
11
10
|
import { PublicDataWrite } from '../avm/public_data_write.js';
|
|
@@ -13,6 +12,7 @@ import { RevertCode } from '../avm/revert_code.js';
|
|
|
13
12
|
import { ContractClassLog } from '../logs/contract_class_log.js';
|
|
14
13
|
import { PrivateLog } from '../logs/private_log.js';
|
|
15
14
|
import { FlatPublicLogs, PublicLog } from '../logs/public_log.js';
|
|
15
|
+
import { computeTxOutHash } from '../messaging/out_hash.js';
|
|
16
16
|
import { TxHash } from './tx_hash.js';
|
|
17
17
|
export class TxEffect {
|
|
18
18
|
revertCode;
|
|
@@ -117,9 +117,6 @@ export class TxEffect {
|
|
|
117
117
|
equals(other) {
|
|
118
118
|
return this.revertCode.equals(other.revertCode) && this.txHash.equals(other.txHash) && this.transactionFee.equals(other.transactionFee) && this.noteHashes.length === other.noteHashes.length && this.noteHashes.every((h, i)=>h.equals(other.noteHashes[i])) && this.nullifiers.length === other.nullifiers.length && this.nullifiers.every((h, i)=>h.equals(other.nullifiers[i])) && this.l2ToL1Msgs.length === other.l2ToL1Msgs.length && this.l2ToL1Msgs.every((h, i)=>h.equals(other.l2ToL1Msgs[i])) && this.publicDataWrites.length === other.publicDataWrites.length && this.publicDataWrites.every((h, i)=>h.equals(other.publicDataWrites[i])) && this.privateLogs.length === other.privateLogs.length && this.privateLogs.every((h, i)=>h.equals(other.privateLogs[i])) && this.publicLogs.length === other.publicLogs.length && this.publicLogs.every((h, i)=>h.equals(other.publicLogs[i])) && this.contractClassLogs.length === other.contractClassLogs.length && this.contractClassLogs.every((h, i)=>h.equals(other.contractClassLogs[i]));
|
|
119
119
|
}
|
|
120
|
-
/** Returns the size of this tx effect in bytes as serialized onto DA. */ getDASize() {
|
|
121
|
-
return this.toBlobFields().length * Fr.SIZE_IN_BYTES;
|
|
122
|
-
}
|
|
123
120
|
/**
|
|
124
121
|
* Deserializes the TxEffect object from a Buffer.
|
|
125
122
|
* @param buffer - Buffer or BufferReader object to deserialize.
|
|
@@ -132,11 +129,7 @@ export class TxEffect {
|
|
|
132
129
|
* Computes txOutHash of this tx effect.
|
|
133
130
|
* @dev Follows new_sha in unbalanced_merkle_tree.nr
|
|
134
131
|
*/ txOutHash() {
|
|
135
|
-
|
|
136
|
-
if (l2ToL1Msgs.length == 0) {
|
|
137
|
-
return Buffer.alloc(32);
|
|
138
|
-
}
|
|
139
|
-
return computeUnbalancedMerkleTreeRoot(l2ToL1Msgs.map((msg)=>msg.toBuffer()));
|
|
132
|
+
return computeTxOutHash(this.l2ToL1Msgs);
|
|
140
133
|
}
|
|
141
134
|
static async random(numPublicCallsPerTx = 3, numPublicLogsPerCall = 1, maxEffects = undefined) {
|
|
142
135
|
return new TxEffect(RevertCode.random(), TxHash.random(), new Fr(Math.floor(Math.random() * 100_000)), makeTuple(maxEffects === undefined ? MAX_NOTE_HASHES_PER_TX : Math.min(maxEffects, MAX_NOTE_HASHES_PER_TX), Fr.random), makeTuple(maxEffects === undefined ? MAX_NULLIFIERS_PER_TX : Math.min(maxEffects, MAX_NULLIFIERS_PER_TX), Fr.random), makeTuple(maxEffects === undefined ? MAX_L2_TO_L1_MSGS_PER_TX : Math.min(maxEffects, MAX_L2_TO_L1_MSGS_PER_TX), Fr.random), makeTuple(maxEffects === undefined ? MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX : Math.min(maxEffects, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX), PublicDataWrite.random), makeTuple(MAX_PRIVATE_LOGS_PER_TX, ()=>PrivateLog.random()), await Promise.all(new Array(numPublicCallsPerTx * numPublicLogsPerCall).fill(null).map(()=>PublicLog.random())), await makeTupleAsync(MAX_CONTRACT_CLASS_LOGS_PER_TX, ContractClassLog.random));
|
|
@@ -147,63 +140,66 @@ export class TxEffect {
|
|
|
147
140
|
/** Returns a hex representation of the TxEffect object. */ toString() {
|
|
148
141
|
return bufferToHex(this.toBuffer());
|
|
149
142
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
flattened.push(...this.publicDataWrites.flatMap((w)=>w.toBlobFields()));
|
|
163
|
-
flattened.push(...this.privateLogs.flatMap((l)=>l.toBlobFields()));
|
|
164
|
-
const flattenedPublicLogs = FlatPublicLogs.fromLogs(this.publicLogs);
|
|
165
|
-
flattened.push(...flattenedPublicLogs.toBlobFields());
|
|
166
|
-
flattened.push(...this.contractClassLogs.flatMap((l)=>l.toBlobFields()));
|
|
167
|
-
flattened[0] = encodeTxStartMarker({
|
|
143
|
+
getNumBlobFields() {
|
|
144
|
+
return this.getTxStartMarker().numBlobFields;
|
|
145
|
+
}
|
|
146
|
+
toBlobFields() {
|
|
147
|
+
return encodeTxBlobData(this.toTxBlobData());
|
|
148
|
+
}
|
|
149
|
+
static fromBlobFields(fields) {
|
|
150
|
+
return TxEffect.fromTxBlobData(decodeTxBlobData(fields));
|
|
151
|
+
}
|
|
152
|
+
getTxStartMarker() {
|
|
153
|
+
const flatPublicLogs = FlatPublicLogs.fromLogs(this.publicLogs);
|
|
154
|
+
const partialTxStartMarker = {
|
|
168
155
|
revertCode: this.revertCode.getCode(),
|
|
169
|
-
numBlobFields: flattened.length,
|
|
170
156
|
numNoteHashes: this.noteHashes.length,
|
|
171
157
|
numNullifiers: this.nullifiers.length,
|
|
172
158
|
numL2ToL1Msgs: this.l2ToL1Msgs.length,
|
|
173
159
|
numPublicDataWrites: this.publicDataWrites.length,
|
|
174
160
|
numPrivateLogs: this.privateLogs.length,
|
|
175
|
-
|
|
161
|
+
privateLogsLength: this.privateLogs.reduce((acc, log)=>acc + log.emittedLength, 0),
|
|
162
|
+
publicLogsLength: flatPublicLogs.length,
|
|
176
163
|
contractClassLogLength: this.contractClassLogs[0]?.emittedLength ?? 0
|
|
177
|
-
}
|
|
178
|
-
|
|
164
|
+
};
|
|
165
|
+
const numBlobFields = getNumTxBlobFields(partialTxStartMarker);
|
|
166
|
+
return {
|
|
167
|
+
...partialTxStartMarker,
|
|
168
|
+
numBlobFields
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Returns a flat packed array of fields of all tx effects, to be appended to blobs.
|
|
173
|
+
* Must match the implementation in noir-protocol-circuits/crates/rollup-lib/src/tx_base/components/tx_blob_data.nr
|
|
174
|
+
*/ toTxBlobData() {
|
|
175
|
+
return {
|
|
176
|
+
txStartMarker: this.getTxStartMarker(),
|
|
177
|
+
txHash: this.txHash.hash,
|
|
178
|
+
transactionFee: this.transactionFee,
|
|
179
|
+
noteHashes: this.noteHashes,
|
|
180
|
+
nullifiers: this.nullifiers,
|
|
181
|
+
l2ToL1Msgs: this.l2ToL1Msgs,
|
|
182
|
+
publicDataWrites: this.publicDataWrites.map((w)=>w.toBlobFields()),
|
|
183
|
+
privateLogs: this.privateLogs.map((l)=>l.toBlobFields()),
|
|
184
|
+
publicLogs: FlatPublicLogs.fromLogs(this.publicLogs).toBlobFields(),
|
|
185
|
+
contractClassLog: this.contractClassLogs.map((l)=>l.toBlobFields()).flat()
|
|
186
|
+
};
|
|
179
187
|
}
|
|
180
188
|
/**
|
|
181
189
|
* Decodes a flat packed array of fields to TxEffect.
|
|
182
|
-
*/ static
|
|
183
|
-
const
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const
|
|
193
|
-
const txHash = new TxHash(reader.readField());
|
|
194
|
-
const transactionFee = reader.readField();
|
|
195
|
-
const noteHashes = reader.readFieldArray(txStartMarker.numNoteHashes);
|
|
196
|
-
const nullifiers = reader.readFieldArray(txStartMarker.numNullifiers);
|
|
197
|
-
const l2ToL1Msgs = reader.readFieldArray(txStartMarker.numL2ToL1Msgs);
|
|
198
|
-
const publicDataWrites = Array.from({
|
|
199
|
-
length: txStartMarker.numPublicDataWrites
|
|
200
|
-
}, ()=>PublicDataWrite.fromBlobFields(reader));
|
|
201
|
-
const privateLogs = Array.from({
|
|
202
|
-
length: txStartMarker.numPrivateLogs
|
|
203
|
-
}, ()=>PrivateLog.fromBlobFields(reader));
|
|
204
|
-
const publicLogs = FlatPublicLogs.fromBlobFields(txStartMarker.publicLogsLength, reader).toLogs();
|
|
190
|
+
*/ static fromTxBlobData(txBlobData) {
|
|
191
|
+
const txStartMarker = txBlobData.txStartMarker;
|
|
192
|
+
const revertCode = RevertCode.fromNumber(txStartMarker.revertCode);
|
|
193
|
+
const txHash = new TxHash(txBlobData.txHash);
|
|
194
|
+
const transactionFee = txBlobData.transactionFee;
|
|
195
|
+
const noteHashes = txBlobData.noteHashes;
|
|
196
|
+
const nullifiers = txBlobData.nullifiers;
|
|
197
|
+
const l2ToL1Msgs = txBlobData.l2ToL1Msgs;
|
|
198
|
+
const publicDataWrites = txBlobData.publicDataWrites.map((w)=>PublicDataWrite.fromBlobFields(w));
|
|
199
|
+
const privateLogs = txBlobData.privateLogs.map((l)=>PrivateLog.fromBlobFields(l.length, l));
|
|
200
|
+
const publicLogs = FlatPublicLogs.fromBlobFields(txStartMarker.publicLogsLength, txBlobData.publicLogs).toLogs();
|
|
205
201
|
const contractClassLogs = txStartMarker.contractClassLogLength > 0 ? [
|
|
206
|
-
ContractClassLog.fromBlobFields(txStartMarker.contractClassLogLength,
|
|
202
|
+
ContractClassLog.fromBlobFields(txStartMarker.contractClassLogLength, txBlobData.contractClassLog)
|
|
207
203
|
] : [];
|
|
208
204
|
return TxEffect.from({
|
|
209
205
|
revertCode,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/stdlib",
|
|
3
|
-
"version": "3.0.0-nightly.
|
|
3
|
+
"version": "3.0.0-nightly.20251115",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"inherits": [
|
|
6
6
|
"../package.common.json",
|
|
@@ -72,13 +72,13 @@
|
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@aws-sdk/client-s3": "^3.892.0",
|
|
75
|
-
"@aztec/bb.js": "3.0.0-nightly.
|
|
76
|
-
"@aztec/blob-lib": "3.0.0-nightly.
|
|
77
|
-
"@aztec/constants": "3.0.0-nightly.
|
|
78
|
-
"@aztec/ethereum": "3.0.0-nightly.
|
|
79
|
-
"@aztec/foundation": "3.0.0-nightly.
|
|
80
|
-
"@aztec/l1-artifacts": "3.0.0-nightly.
|
|
81
|
-
"@aztec/noir-noirc_abi": "3.0.0-nightly.
|
|
75
|
+
"@aztec/bb.js": "3.0.0-nightly.20251115",
|
|
76
|
+
"@aztec/blob-lib": "3.0.0-nightly.20251115",
|
|
77
|
+
"@aztec/constants": "3.0.0-nightly.20251115",
|
|
78
|
+
"@aztec/ethereum": "3.0.0-nightly.20251115",
|
|
79
|
+
"@aztec/foundation": "3.0.0-nightly.20251115",
|
|
80
|
+
"@aztec/l1-artifacts": "3.0.0-nightly.20251115",
|
|
81
|
+
"@aztec/noir-noirc_abi": "3.0.0-nightly.20251115",
|
|
82
82
|
"@google-cloud/storage": "^7.15.0",
|
|
83
83
|
"axios": "^1.12.0",
|
|
84
84
|
"json-stringify-deterministic": "1.0.12",
|
package/src/avm/avm.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEFAULT_MAX_DEBUG_LOG_MEMORY_READS } from '@aztec/constants';
|
|
1
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
3
|
import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
|
|
3
4
|
|
|
@@ -1056,7 +1057,7 @@ export class PublicTxResult {
|
|
|
1056
1057
|
public gasUsed: GasUsed,
|
|
1057
1058
|
public revertCode: RevertCode,
|
|
1058
1059
|
public revertReason: SimulationError | undefined, // Revert reason, if any
|
|
1059
|
-
// These are only guaranteed to be present
|
|
1060
|
+
// These are only guaranteed to be present if the simulator is configured to collect them.
|
|
1060
1061
|
public processedPhases: ProcessedPhase[] | undefined,
|
|
1061
1062
|
public logs: DebugLog[] | undefined,
|
|
1062
1063
|
// For the proving request.
|
|
@@ -1121,17 +1122,52 @@ export class PublicTxResult {
|
|
|
1121
1122
|
}
|
|
1122
1123
|
}
|
|
1123
1124
|
|
|
1124
|
-
export
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1125
|
+
export class PublicSimulatorConfig {
|
|
1126
|
+
constructor(
|
|
1127
|
+
public readonly proverId: Fr,
|
|
1128
|
+
public readonly skipFeeEnforcement: boolean,
|
|
1129
|
+
public readonly collectCallMetadata: boolean, // processedPhases.
|
|
1130
|
+
public readonly collectHints: boolean, // hints.
|
|
1131
|
+
public readonly collectDebugLogs: boolean, // logs.
|
|
1132
|
+
public readonly maxDebugLogMemoryReads: number,
|
|
1133
|
+
public readonly collectStatistics: boolean, // timings etc.
|
|
1134
|
+
) {}
|
|
1135
|
+
|
|
1136
|
+
static from(obj: Partial<PublicSimulatorConfig>): PublicSimulatorConfig {
|
|
1137
|
+
return new PublicSimulatorConfig(
|
|
1138
|
+
obj.proverId ?? Fr.ZERO,
|
|
1139
|
+
obj.skipFeeEnforcement ?? false,
|
|
1140
|
+
obj.collectCallMetadata ?? false,
|
|
1141
|
+
obj.collectHints ?? false,
|
|
1142
|
+
obj.collectDebugLogs ?? false,
|
|
1143
|
+
obj.maxDebugLogMemoryReads ?? DEFAULT_MAX_DEBUG_LOG_MEMORY_READS,
|
|
1144
|
+
obj.collectStatistics ?? false,
|
|
1145
|
+
);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
static empty() {
|
|
1149
|
+
return PublicSimulatorConfig.from({});
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
static get schema() {
|
|
1153
|
+
return z
|
|
1154
|
+
.object({
|
|
1155
|
+
proverId: Fr.schema,
|
|
1156
|
+
skipFeeEnforcement: z.boolean(),
|
|
1157
|
+
collectCallMetadata: z.boolean(),
|
|
1158
|
+
collectHints: z.boolean(),
|
|
1159
|
+
collectDebugLogs: z.boolean(),
|
|
1160
|
+
maxDebugLogMemoryReads: z.number(),
|
|
1161
|
+
collectStatistics: z.boolean(),
|
|
1162
|
+
})
|
|
1163
|
+
.transform(PublicSimulatorConfig.from);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1131
1166
|
|
|
1132
1167
|
export class AvmFastSimulationInputs {
|
|
1133
1168
|
constructor(
|
|
1134
1169
|
public readonly wsRevision: WorldStateRevision,
|
|
1170
|
+
public readonly config: PublicSimulatorConfig,
|
|
1135
1171
|
public tx: AvmTxHint,
|
|
1136
1172
|
public globalVariables: GlobalVariables,
|
|
1137
1173
|
public protocolContracts: ProtocolContracts,
|
|
@@ -1140,6 +1176,7 @@ export class AvmFastSimulationInputs {
|
|
|
1140
1176
|
static empty() {
|
|
1141
1177
|
return new AvmFastSimulationInputs(
|
|
1142
1178
|
WorldStateRevision.empty(),
|
|
1179
|
+
PublicSimulatorConfig.empty(),
|
|
1143
1180
|
AvmTxHint.empty(),
|
|
1144
1181
|
GlobalVariables.empty(),
|
|
1145
1182
|
ProtocolContracts.empty(),
|
|
@@ -1150,13 +1187,14 @@ export class AvmFastSimulationInputs {
|
|
|
1150
1187
|
return z
|
|
1151
1188
|
.object({
|
|
1152
1189
|
wsRevision: WorldStateRevision.schema,
|
|
1190
|
+
config: PublicSimulatorConfig.schema,
|
|
1153
1191
|
tx: AvmTxHint.schema,
|
|
1154
1192
|
globalVariables: GlobalVariables.schema,
|
|
1155
1193
|
protocolContracts: ProtocolContracts.schema,
|
|
1156
1194
|
})
|
|
1157
1195
|
.transform(
|
|
1158
|
-
({ wsRevision, tx, globalVariables, protocolContracts }) =>
|
|
1159
|
-
new AvmFastSimulationInputs(wsRevision, tx, globalVariables, protocolContracts),
|
|
1196
|
+
({ wsRevision, config, tx, globalVariables, protocolContracts }) =>
|
|
1197
|
+
new AvmFastSimulationInputs(wsRevision, config, tx, globalVariables, protocolContracts),
|
|
1160
1198
|
);
|
|
1161
1199
|
}
|
|
1162
1200
|
|
package/src/avm/revert_code.ts
CHANGED
|
@@ -115,11 +115,15 @@ export class RevertCode {
|
|
|
115
115
|
return this.toBuffer().length;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
public static
|
|
119
|
-
if (!isRevertCodeEnum(
|
|
120
|
-
throw new Error(`Invalid RevertCode: ${
|
|
118
|
+
public static fromNumber(code: number): RevertCode {
|
|
119
|
+
if (!isRevertCodeEnum(code)) {
|
|
120
|
+
throw new Error(`Invalid RevertCode: ${code}`);
|
|
121
121
|
}
|
|
122
|
-
return new RevertCode(
|
|
122
|
+
return new RevertCode(code);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public static fromField(field: Fr): RevertCode {
|
|
126
|
+
return RevertCode.fromNumber(field.toNumber());
|
|
123
127
|
}
|
|
124
128
|
|
|
125
129
|
public static fromFields(fields: Fr[] | FieldReader): RevertCode {
|
|
@@ -130,10 +134,7 @@ export class RevertCode {
|
|
|
130
134
|
public static fromBuffer(buffer: Buffer | BufferReader): RevertCode {
|
|
131
135
|
const reader = BufferReader.asReader(buffer);
|
|
132
136
|
const code = reader.readBytes(RevertCode.PACKED_SIZE_IN_BYTES).readUInt8(0);
|
|
133
|
-
|
|
134
|
-
throw new Error(`Invalid RevertCode: ${code}`);
|
|
135
|
-
}
|
|
136
|
-
return new RevertCode(code);
|
|
137
|
+
return RevertCode.fromNumber(code);
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
private static readonly NUM_OPTIONS = 4;
|
package/src/block/body.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { TxBlobData } from '@aztec/blob-lib/encoding';
|
|
2
2
|
import { timesParallel } from '@aztec/foundation/collection';
|
|
3
|
-
import {
|
|
4
|
-
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
|
+
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
5
4
|
|
|
6
5
|
import { inspect } from 'util';
|
|
7
6
|
import { z } from 'zod';
|
|
@@ -9,14 +8,6 @@ import { z } from 'zod';
|
|
|
9
8
|
import type { ZodFor } from '../schemas/index.js';
|
|
10
9
|
import { TxEffect } from '../tx/tx_effect.js';
|
|
11
10
|
|
|
12
|
-
export { createBlockEndMarker };
|
|
13
|
-
|
|
14
|
-
export function getBlockBlobFields(txEffects: TxEffect[]) {
|
|
15
|
-
const blobFields = txEffects.flatMap(txEffect => txEffect.toBlobFields());
|
|
16
|
-
blobFields.push(createBlockEndMarker(txEffects.length));
|
|
17
|
-
return blobFields;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
11
|
export class Body {
|
|
21
12
|
constructor(public txEffects: TxEffect[]) {}
|
|
22
13
|
|
|
@@ -55,32 +46,16 @@ export class Body {
|
|
|
55
46
|
/**
|
|
56
47
|
* Returns a flat packed array of fields of all tx effects - used for blobs.
|
|
57
48
|
*/
|
|
58
|
-
|
|
59
|
-
return
|
|
49
|
+
toTxBlobData(): TxBlobData[] {
|
|
50
|
+
return this.txEffects.map(txEffect => txEffect.toTxBlobData());
|
|
60
51
|
}
|
|
61
52
|
|
|
62
53
|
/**
|
|
63
54
|
* Decodes a block from blob fields.
|
|
64
55
|
*/
|
|
65
|
-
static
|
|
66
|
-
const txEffects
|
|
67
|
-
|
|
68
|
-
while (!reader.isFinished()) {
|
|
69
|
-
txEffects.push(TxEffect.fromBlobFields(reader));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// If the fields are from a proven block, or are constructed by calling `toBlobFields`, the following errors should never throw.
|
|
73
|
-
|
|
74
|
-
if (!isBlockEndMarker(fields[fields.length - 1])) {
|
|
75
|
-
throw new Error('Block end marker not found');
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const numTxs = getNumTxsFromBlockEndMarker(fields[fields.length - 1]);
|
|
79
|
-
if (numTxs !== txEffects.length) {
|
|
80
|
-
throw new Error(`Expected ${numTxs} txs, but got ${txEffects.length}`);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return new this(txEffects);
|
|
56
|
+
static fromTxBlobData(txBlobData: TxBlobData[]): Body {
|
|
57
|
+
const txEffects = txBlobData.map(data => TxEffect.fromTxBlobData(data));
|
|
58
|
+
return new Body(txEffects);
|
|
84
59
|
}
|
|
85
60
|
|
|
86
61
|
[inspect.custom]() {
|
package/src/block/index.ts
CHANGED
package/src/block/l2_block.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { type BlockBlobData, encodeBlockBlobData } from '@aztec/blob-lib/encoding';
|
|
1
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
3
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
4
|
import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
|
|
4
5
|
|
|
5
6
|
import { z } from 'zod';
|
|
6
7
|
|
|
7
|
-
import { getCheckpointBlobFields } from '../checkpoint/checkpoint_body.js';
|
|
8
8
|
import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
|
|
9
9
|
import type { BlockHeader } from '../tx/block_header.js';
|
|
10
10
|
import { Body } from './body.js';
|
|
@@ -14,6 +14,8 @@ import type { L2BlockInfo } from './l2_block_info.js';
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* The data that makes up the rollup proof, with encoder decoder functions.
|
|
17
|
+
*
|
|
18
|
+
* @deprecated Use `L2BlockNew` instead.
|
|
17
19
|
*/
|
|
18
20
|
export class L2Block {
|
|
19
21
|
constructor(
|
|
@@ -152,7 +154,36 @@ export class L2Block {
|
|
|
152
154
|
* TODO(#17027): Remove this method from L2Block and create a dedicated Checkpoint class.
|
|
153
155
|
*/
|
|
154
156
|
public getCheckpointBlobFields() {
|
|
155
|
-
|
|
157
|
+
const blockBlobData = this.toBlobFields(true);
|
|
158
|
+
return [new Fr(blockBlobData.length + 1)].concat(blockBlobData);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public toBlobFields(isFirstBlock: boolean): Fr[] {
|
|
162
|
+
const blockBlobData = this.toBlockBlobData(isFirstBlock);
|
|
163
|
+
return encodeBlockBlobData(blockBlobData);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public toBlockBlobData(isFirstBlock: boolean): BlockBlobData {
|
|
167
|
+
return {
|
|
168
|
+
blockEndMarker: {
|
|
169
|
+
numTxs: this.body.txEffects.length,
|
|
170
|
+
timestamp: this.header.globalVariables.timestamp,
|
|
171
|
+
blockNumber: this.number,
|
|
172
|
+
},
|
|
173
|
+
blockEndStateField: {
|
|
174
|
+
l1ToL2MessageNextAvailableLeafIndex: this.header.state.l1ToL2MessageTree.nextAvailableLeafIndex,
|
|
175
|
+
noteHashNextAvailableLeafIndex: this.header.state.partial.noteHashTree.nextAvailableLeafIndex,
|
|
176
|
+
nullifierNextAvailableLeafIndex: this.header.state.partial.nullifierTree.nextAvailableLeafIndex,
|
|
177
|
+
publicDataNextAvailableLeafIndex: this.header.state.partial.publicDataTree.nextAvailableLeafIndex,
|
|
178
|
+
totalManaUsed: this.header.totalManaUsed.toBigInt(),
|
|
179
|
+
},
|
|
180
|
+
lastArchiveRoot: this.header.lastArchive.root,
|
|
181
|
+
noteHashRoot: this.header.state.partial.noteHashTree.root,
|
|
182
|
+
nullifierRoot: this.header.state.partial.nullifierTree.root,
|
|
183
|
+
publicDataRoot: this.header.state.partial.publicDataTree.root,
|
|
184
|
+
l1ToL2MessageRoot: isFirstBlock ? this.header.state.l1ToL2MessageTree.root : undefined,
|
|
185
|
+
txs: this.body.toTxBlobData(),
|
|
186
|
+
};
|
|
156
187
|
}
|
|
157
188
|
|
|
158
189
|
/**
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { type BlockBlobData, encodeBlockBlobData } from '@aztec/blob-lib/encoding';
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
4
|
+
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
|
|
8
|
+
import { BlockHeader } from '../tx/block_header.js';
|
|
9
|
+
import { Body } from './body.js';
|
|
10
|
+
import type { L2BlockInfo } from './l2_block_info.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* An L2 block with a header and a body.
|
|
14
|
+
* TODO: Delete the existing `L2Block` class and rename this to `L2Block`.
|
|
15
|
+
*/
|
|
16
|
+
export class L2BlockNew {
|
|
17
|
+
constructor(
|
|
18
|
+
/** Snapshot of archive tree after the block is applied. */
|
|
19
|
+
public archive: AppendOnlyTreeSnapshot,
|
|
20
|
+
/** Header of the block. */
|
|
21
|
+
public header: BlockHeader,
|
|
22
|
+
/** L2 block body. */
|
|
23
|
+
public body: Body,
|
|
24
|
+
private blockHash: Fr | undefined = undefined,
|
|
25
|
+
) {}
|
|
26
|
+
|
|
27
|
+
get number(): number {
|
|
28
|
+
return this.header.globalVariables.blockNumber;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get timestamp(): bigint {
|
|
32
|
+
return this.header.globalVariables.timestamp;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static get schema() {
|
|
36
|
+
return z
|
|
37
|
+
.object({
|
|
38
|
+
archive: AppendOnlyTreeSnapshot.schema,
|
|
39
|
+
header: BlockHeader.schema,
|
|
40
|
+
body: Body.schema,
|
|
41
|
+
})
|
|
42
|
+
.transform(({ archive, header, body }) => new L2BlockNew(archive, header, body));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Deserializes a block from a buffer
|
|
47
|
+
* @returns A deserialized L2 block.
|
|
48
|
+
*/
|
|
49
|
+
static fromBuffer(buf: Buffer | BufferReader) {
|
|
50
|
+
const reader = BufferReader.asReader(buf);
|
|
51
|
+
const header = reader.readObject(BlockHeader);
|
|
52
|
+
const archive = reader.readObject(AppendOnlyTreeSnapshot);
|
|
53
|
+
const body = reader.readObject(Body);
|
|
54
|
+
|
|
55
|
+
return new L2BlockNew(archive, header, body);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Serializes a block
|
|
60
|
+
* @returns A serialized L2 block as a Buffer.
|
|
61
|
+
*/
|
|
62
|
+
toBuffer() {
|
|
63
|
+
return serializeToBuffer(this.header, this.archive, this.body);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Returns the block's hash (hash of block header).
|
|
68
|
+
* @returns The block's hash.
|
|
69
|
+
*/
|
|
70
|
+
public async hash(): Promise<Fr> {
|
|
71
|
+
if (this.blockHash === undefined) {
|
|
72
|
+
this.blockHash = await this.header.hash();
|
|
73
|
+
}
|
|
74
|
+
return this.blockHash;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public toBlobFields(isFirstBlock: boolean): Fr[] {
|
|
78
|
+
const blockBlobData = this.toBlockBlobData(isFirstBlock);
|
|
79
|
+
return encodeBlockBlobData(blockBlobData);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public toBlockBlobData(isFirstBlock: boolean): BlockBlobData {
|
|
83
|
+
return {
|
|
84
|
+
blockEndMarker: {
|
|
85
|
+
numTxs: this.body.txEffects.length,
|
|
86
|
+
timestamp: this.header.globalVariables.timestamp,
|
|
87
|
+
blockNumber: this.number,
|
|
88
|
+
},
|
|
89
|
+
blockEndStateField: {
|
|
90
|
+
l1ToL2MessageNextAvailableLeafIndex: this.header.state.l1ToL2MessageTree.nextAvailableLeafIndex,
|
|
91
|
+
noteHashNextAvailableLeafIndex: this.header.state.partial.noteHashTree.nextAvailableLeafIndex,
|
|
92
|
+
nullifierNextAvailableLeafIndex: this.header.state.partial.nullifierTree.nextAvailableLeafIndex,
|
|
93
|
+
publicDataNextAvailableLeafIndex: this.header.state.partial.publicDataTree.nextAvailableLeafIndex,
|
|
94
|
+
totalManaUsed: this.header.totalManaUsed.toBigInt(),
|
|
95
|
+
},
|
|
96
|
+
lastArchiveRoot: this.header.lastArchive.root,
|
|
97
|
+
noteHashRoot: this.header.state.partial.noteHashTree.root,
|
|
98
|
+
nullifierRoot: this.header.state.partial.nullifierTree.root,
|
|
99
|
+
publicDataRoot: this.header.state.partial.publicDataTree.root,
|
|
100
|
+
l1ToL2MessageRoot: isFirstBlock ? this.header.state.l1ToL2MessageTree.root : undefined,
|
|
101
|
+
txs: this.body.toTxBlobData(),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Returns stats used for logging.
|
|
107
|
+
* @returns Stats on tx count, number, and log size and count.
|
|
108
|
+
*/
|
|
109
|
+
getStats() {
|
|
110
|
+
const logsStats = {
|
|
111
|
+
privateLogCount: this.body.txEffects.reduce((logCount, txEffect) => logCount + txEffect.privateLogs.length, 0),
|
|
112
|
+
publicLogCount: this.body.txEffects.reduce((logCount, txEffect) => logCount + txEffect.publicLogs.length, 0),
|
|
113
|
+
contractClassLogCount: this.body.txEffects.reduce(
|
|
114
|
+
(logCount, txEffect) => logCount + txEffect.contractClassLogs.length,
|
|
115
|
+
0,
|
|
116
|
+
),
|
|
117
|
+
contractClassLogSize: this.body.txEffects.reduce(
|
|
118
|
+
(totalLogSize, txEffect) =>
|
|
119
|
+
totalLogSize + txEffect.contractClassLogs.reduce((acc, log) => acc + log.emittedLength, 0),
|
|
120
|
+
0,
|
|
121
|
+
),
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
txCount: this.body.txEffects.length,
|
|
126
|
+
blockNumber: this.number,
|
|
127
|
+
blockTimestamp: Number(this.header.globalVariables.timestamp),
|
|
128
|
+
...logsStats,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
toBlockInfo(): L2BlockInfo {
|
|
133
|
+
return {
|
|
134
|
+
blockHash: this.blockHash,
|
|
135
|
+
archive: this.archive.root,
|
|
136
|
+
lastArchive: this.header.lastArchive.root,
|
|
137
|
+
blockNumber: this.number,
|
|
138
|
+
slotNumber: Number(this.header.getSlot()),
|
|
139
|
+
txCount: this.body.txEffects.length,
|
|
140
|
+
timestamp: this.header.globalVariables.timestamp,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
|
+
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
import { L2BlockNew } from '../block/l2_block_new.js';
|
|
7
|
+
import { CheckpointHeader } from '../rollup/checkpoint_header.js';
|
|
8
|
+
import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
|
|
9
|
+
|
|
10
|
+
export class Checkpoint {
|
|
11
|
+
constructor(
|
|
12
|
+
/** Snapshot of archive tree after the checkpoint is added. */
|
|
13
|
+
public archive: AppendOnlyTreeSnapshot,
|
|
14
|
+
/** Header of the checkpoint. */
|
|
15
|
+
public header: CheckpointHeader,
|
|
16
|
+
/** L2 blocks in the checkpoint. */
|
|
17
|
+
public blocks: L2BlockNew[],
|
|
18
|
+
) {}
|
|
19
|
+
|
|
20
|
+
static get schema() {
|
|
21
|
+
return z
|
|
22
|
+
.object({
|
|
23
|
+
archive: AppendOnlyTreeSnapshot.schema,
|
|
24
|
+
header: CheckpointHeader.schema,
|
|
25
|
+
blocks: z.array(L2BlockNew.schema),
|
|
26
|
+
})
|
|
27
|
+
.transform(({ archive, header, blocks }) => new Checkpoint(archive, header, blocks));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static fromBuffer(buf: Buffer | BufferReader) {
|
|
31
|
+
const reader = BufferReader.asReader(buf);
|
|
32
|
+
const archive = reader.readObject(AppendOnlyTreeSnapshot);
|
|
33
|
+
const header = reader.readObject(CheckpointHeader);
|
|
34
|
+
const blocks = reader.readVector(L2BlockNew);
|
|
35
|
+
return new Checkpoint(archive, header, blocks);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
toBuffer() {
|
|
39
|
+
return serializeToBuffer(this.archive, this.header, this.blocks.length, this.blocks);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public toBlobFields() {
|
|
43
|
+
const blocksBlobFields = this.blocks.flatMap((block, i) => block.toBlobFields(i === 0));
|
|
44
|
+
return [new Fr(blocksBlobFields.length + 1)].concat(blocksBlobFields);
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/checkpoint/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './checkpoint.js';
|
package/src/logs/private_log.ts
CHANGED
|
@@ -49,12 +49,11 @@ export class PrivateLog {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
toBlobFields(): Fr[] {
|
|
52
|
-
return
|
|
52
|
+
return this.getEmittedFields();
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
static fromBlobFields(fields: Fr[] | FieldReader) {
|
|
55
|
+
static fromBlobFields(emittedLength: number, fields: Fr[] | FieldReader) {
|
|
56
56
|
const reader = FieldReader.asReader(fields);
|
|
57
|
-
const emittedLength = reader.readU32();
|
|
58
57
|
const emittedFields = reader.readFieldArray(emittedLength);
|
|
59
58
|
return new PrivateLog(padArrayEnd(emittedFields, Fr.ZERO, PRIVATE_LOG_SIZE_IN_FIELDS), emittedLength);
|
|
60
59
|
}
|