@@ -18,25 +18,32 @@ import {
18
18
type GasSettings ,
19
19
type GlobalVariables ,
20
20
MAX_L2_GAS_PER_TX_PUBLIC_PORTION ,
21
+ MAX_L2_TO_L1_MSGS_PER_TX ,
21
22
MAX_NOTE_HASHES_PER_TX ,
22
23
MAX_NULLIFIERS_PER_TX ,
24
+ MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX ,
25
+ PrivateToAvmAccumulatedData ,
26
+ PrivateToAvmAccumulatedDataArrayLengths ,
23
27
type PrivateToPublicAccumulatedData ,
24
- type PublicCallRequest ,
28
+ PublicCallRequest ,
29
+ PublicDataWrite ,
25
30
RevertCode ,
26
31
type StateReference ,
27
32
TreeSnapshots ,
28
33
computeTransactionFee ,
29
34
countAccumulatedItems ,
35
+ mergeAccumulatedData ,
30
36
} from '@aztec/circuits.js' ;
37
+ import { padArrayEnd } from '@aztec/foundation/collection' ;
31
38
import { type Logger , createLogger } from '@aztec/foundation/log' ;
39
+ import { assertLength } from '@aztec/foundation/serialize' ;
32
40
33
41
import { strict as assert } from 'assert' ;
34
42
import { inspect } from 'util' ;
35
43
36
44
import { AvmPersistableStateManager } from '../avm/index.js' ;
37
45
import { type WorldStateDB } from './public_db_sources.js' ;
38
46
import { SideEffectArrayLengths , SideEffectTrace } from './side_effect_trace.js' ;
39
- import { generateAvmCircuitPublicInputs } from './transitional_adapters.js' ;
40
47
import { getCallRequestsByPhase , getExecutionRequestsByPhase } from './utils.js' ;
41
48
42
49
/**
@@ -350,23 +357,78 @@ export class PublicTxContext {
350
357
publicDataTree ,
351
358
) ;
352
359
353
- return generateAvmCircuitPublicInputs (
354
- this . trace ,
360
+ const startTreeSnapshots = new TreeSnapshots (
361
+ this . startStateReference . l1ToL2MessageTree ,
362
+ this . startStateReference . partial . noteHashTree ,
363
+ this . startStateReference . partial . nullifierTree ,
364
+ this . startStateReference . partial . publicDataTree ,
365
+ ) ;
366
+
367
+ const avmCircuitPublicInputs = this . trace . toAvmCircuitPublicInputs (
355
368
this . globalVariables ,
356
- this . startStateReference ,
369
+ startTreeSnapshots ,
357
370
/*startGasUsed=*/ this . gasUsedByPrivate ,
358
371
this . gasSettings ,
359
372
this . feePayer ,
360
373
this . setupCallRequests ,
361
374
this . appLogicCallRequests ,
362
- this . teardownCallRequests ,
363
- this . nonRevertibleAccumulatedDataFromPrivate ,
364
- this . revertibleAccumulatedDataFromPrivate ,
375
+ /*teardownCallRequest=*/ this . teardownCallRequests . length
376
+ ? this . teardownCallRequests [ 0 ]
377
+ : PublicCallRequest . empty ( ) ,
365
378
endTreeSnapshots ,
366
379
/*endGasUsed=*/ this . getTotalGasUsed ( ) ,
367
- this . getTransactionFeeUnsafe ( ) ,
368
- this . revertCode ,
380
+ /*transactionFee=*/ this . getTransactionFeeUnsafe ( ) ,
381
+ /*reverted=*/ ! this . revertCode . isOK ( ) ,
369
382
) ;
383
+
384
+ const getArrayLengths = ( from : PrivateToPublicAccumulatedData ) =>
385
+ new PrivateToAvmAccumulatedDataArrayLengths (
386
+ countAccumulatedItems ( from . noteHashes ) ,
387
+ countAccumulatedItems ( from . nullifiers ) ,
388
+ countAccumulatedItems ( from . l2ToL1Msgs ) ,
389
+ ) ;
390
+ const convertAccumulatedData = ( from : PrivateToPublicAccumulatedData ) =>
391
+ new PrivateToAvmAccumulatedData ( from . noteHashes , from . nullifiers , from . l2ToL1Msgs ) ;
392
+ // Temporary overrides as these entries aren't yet populated in trace
393
+ avmCircuitPublicInputs . previousNonRevertibleAccumulatedDataArrayLengths = getArrayLengths (
394
+ this . nonRevertibleAccumulatedDataFromPrivate ,
395
+ ) ;
396
+ avmCircuitPublicInputs . previousRevertibleAccumulatedDataArrayLengths = getArrayLengths (
397
+ this . revertibleAccumulatedDataFromPrivate ,
398
+ ) ;
399
+ avmCircuitPublicInputs . previousNonRevertibleAccumulatedData = convertAccumulatedData (
400
+ this . nonRevertibleAccumulatedDataFromPrivate ,
401
+ ) ;
402
+ avmCircuitPublicInputs . previousRevertibleAccumulatedData = convertAccumulatedData (
403
+ this . revertibleAccumulatedDataFromPrivate ,
404
+ ) ;
405
+
406
+ const msgsFromPrivate = this . revertCode . isOK ( )
407
+ ? mergeAccumulatedData (
408
+ avmCircuitPublicInputs . previousNonRevertibleAccumulatedData . l2ToL1Msgs ,
409
+ avmCircuitPublicInputs . previousRevertibleAccumulatedData . l2ToL1Msgs ,
410
+ )
411
+ : avmCircuitPublicInputs . previousNonRevertibleAccumulatedData . l2ToL1Msgs ;
412
+ avmCircuitPublicInputs . accumulatedData . l2ToL1Msgs = assertLength (
413
+ mergeAccumulatedData ( msgsFromPrivate , avmCircuitPublicInputs . accumulatedData . l2ToL1Msgs ) ,
414
+ MAX_L2_TO_L1_MSGS_PER_TX ,
415
+ ) ;
416
+
417
+ // Maps slot to value. Maps in TS are iterable in insertion order, which is exactly what we want for
418
+ // squashing "to the left", where the first occurrence of a slot uses the value of the last write to it,
419
+ // and the rest occurrences are omitted
420
+ const squashedPublicDataWrites : Map < bigint , Fr > = new Map ( ) ;
421
+ for ( const publicDataWrite of avmCircuitPublicInputs . accumulatedData . publicDataWrites ) {
422
+ squashedPublicDataWrites . set ( publicDataWrite . leafSlot . toBigInt ( ) , publicDataWrite . value ) ;
423
+ }
424
+
425
+ avmCircuitPublicInputs . accumulatedData . publicDataWrites = padArrayEnd (
426
+ Array . from ( squashedPublicDataWrites . entries ( ) ) . map ( ( [ slot , value ] ) => new PublicDataWrite ( new Fr ( slot ) , value ) ) ,
427
+ PublicDataWrite . empty ( ) ,
428
+ MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX ,
429
+ ) ;
430
+
431
+ return avmCircuitPublicInputs ;
370
432
}
371
433
372
434
/**
0 commit comments