@aztec/txe 3.0.0-nightly.20251216 → 3.0.0-nightly.20251217

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.
Files changed (39) hide show
  1. package/dest/index.d.ts +1 -1
  2. package/dest/index.d.ts.map +1 -1
  3. package/dest/index.js +3 -2
  4. package/dest/oracle/txe_oracle_public_context.d.ts +2 -2
  5. package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
  6. package/dest/oracle/txe_oracle_public_context.js +3 -5
  7. package/dest/oracle/txe_oracle_top_level_context.d.ts +1 -1
  8. package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
  9. package/dest/oracle/txe_oracle_top_level_context.js +13 -14
  10. package/dest/rpc_translator.d.ts +3 -3
  11. package/dest/rpc_translator.d.ts.map +1 -1
  12. package/dest/rpc_translator.js +2 -2
  13. package/dest/state_machine/archiver.d.ts +13 -7
  14. package/dest/state_machine/archiver.d.ts.map +1 -1
  15. package/dest/state_machine/archiver.js +83 -15
  16. package/dest/state_machine/dummy_p2p_client.d.ts +1 -1
  17. package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
  18. package/dest/state_machine/dummy_p2p_client.js +3 -1
  19. package/dest/state_machine/index.d.ts +5 -5
  20. package/dest/state_machine/index.d.ts.map +1 -1
  21. package/dest/state_machine/index.js +13 -19
  22. package/dest/txe_session.d.ts +1 -1
  23. package/dest/txe_session.d.ts.map +1 -1
  24. package/dest/txe_session.js +10 -9
  25. package/dest/util/encoding.d.ts +601 -2
  26. package/dest/util/encoding.d.ts.map +1 -1
  27. package/dest/utils/block_creation.d.ts +16 -2
  28. package/dest/utils/block_creation.d.ts.map +1 -1
  29. package/dest/utils/block_creation.js +22 -1
  30. package/package.json +15 -15
  31. package/src/index.ts +14 -11
  32. package/src/oracle/txe_oracle_public_context.ts +3 -8
  33. package/src/oracle/txe_oracle_top_level_context.ts +16 -38
  34. package/src/rpc_translator.ts +2 -2
  35. package/src/state_machine/archiver.ts +106 -21
  36. package/src/state_machine/dummy_p2p_client.ts +3 -1
  37. package/src/state_machine/index.ts +18 -17
  38. package/src/txe_session.ts +19 -17
  39. package/src/utils/block_creation.ts +31 -1
@@ -1,7 +1,7 @@
1
1
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
2
2
  import { padArrayEnd } from '@aztec/foundation/collection';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
- import { L2BlockHeader } from '@aztec/stdlib/block';
4
+ import { Body, L2Block, L2BlockHeader } from '@aztec/stdlib/block';
5
5
  import { makeContentCommitment } from '@aztec/stdlib/testing';
6
6
  import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
7
7
  /**
@@ -22,3 +22,24 @@ export async function makeTXEBlockHeader(worldTrees, globalVariables) {
22
22
  const archiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
23
23
  return new L2BlockHeader(new AppendOnlyTreeSnapshot(new Fr(archiveInfo.root), Number(archiveInfo.size)), makeContentCommitment(), stateReference, globalVariables, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO);
24
24
  }
25
+ /**
26
+ * Creates an L2Block with proper archive chaining.
27
+ * This function:
28
+ * 1. Gets the current archive state as lastArchive for the header
29
+ * 2. Creates the block header
30
+ * 3. Updates the archive tree with the header hash
31
+ * 4. Gets the new archive state for the block's archive
32
+ *
33
+ * @param worldTrees - The world trees to read/write from
34
+ * @param globalVariables - Global variables for the block
35
+ * @param txEffects - Transaction effects to include in the block
36
+ * @returns The created L2Block with proper archive chaining
37
+ */ export async function makeTXEBlock(worldTrees, globalVariables, txEffects) {
38
+ const header = await makeTXEBlockHeader(worldTrees, globalVariables);
39
+ // Update the archive tree with this block's header hash
40
+ await worldTrees.updateArchive(header.toBlockHeader());
41
+ // Get the new archive state after updating
42
+ const newArchiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
43
+ const newArchive = new AppendOnlyTreeSnapshot(new Fr(newArchiveInfo.root), Number(newArchiveInfo.size));
44
+ return new L2Block(newArchive, header, new Body(txEffects));
45
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/txe",
3
- "version": "3.0.0-nightly.20251216",
3
+ "version": "3.0.0-nightly.20251217",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "bin": "./dest/bin/index.js",
@@ -61,20 +61,20 @@
61
61
  ]
62
62
  },
63
63
  "dependencies": {
64
- "@aztec/accounts": "3.0.0-nightly.20251216",
65
- "@aztec/archiver": "3.0.0-nightly.20251216",
66
- "@aztec/aztec-node": "3.0.0-nightly.20251216",
67
- "@aztec/aztec.js": "3.0.0-nightly.20251216",
68
- "@aztec/bb-prover": "3.0.0-nightly.20251216",
69
- "@aztec/constants": "3.0.0-nightly.20251216",
70
- "@aztec/foundation": "3.0.0-nightly.20251216",
71
- "@aztec/key-store": "3.0.0-nightly.20251216",
72
- "@aztec/kv-store": "3.0.0-nightly.20251216",
73
- "@aztec/protocol-contracts": "3.0.0-nightly.20251216",
74
- "@aztec/pxe": "3.0.0-nightly.20251216",
75
- "@aztec/simulator": "3.0.0-nightly.20251216",
76
- "@aztec/stdlib": "3.0.0-nightly.20251216",
77
- "@aztec/world-state": "3.0.0-nightly.20251216",
64
+ "@aztec/accounts": "3.0.0-nightly.20251217",
65
+ "@aztec/archiver": "3.0.0-nightly.20251217",
66
+ "@aztec/aztec-node": "3.0.0-nightly.20251217",
67
+ "@aztec/aztec.js": "3.0.0-nightly.20251217",
68
+ "@aztec/bb-prover": "3.0.0-nightly.20251217",
69
+ "@aztec/constants": "3.0.0-nightly.20251217",
70
+ "@aztec/foundation": "3.0.0-nightly.20251217",
71
+ "@aztec/key-store": "3.0.0-nightly.20251217",
72
+ "@aztec/kv-store": "3.0.0-nightly.20251217",
73
+ "@aztec/protocol-contracts": "3.0.0-nightly.20251217",
74
+ "@aztec/pxe": "3.0.0-nightly.20251217",
75
+ "@aztec/simulator": "3.0.0-nightly.20251217",
76
+ "@aztec/stdlib": "3.0.0-nightly.20251217",
77
+ "@aztec/world-state": "3.0.0-nightly.20251217",
78
78
  "zod": "^3.23.8"
79
79
  },
80
80
  "devDependencies": {
package/src/index.ts CHANGED
@@ -12,7 +12,8 @@ import type { Logger } from '@aztec/foundation/log';
12
12
  import { type ProtocolContract, protocolContractNames } from '@aztec/protocol-contracts';
13
13
  import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
14
14
  import { computeArtifactHash } from '@aztec/stdlib/contract';
15
- import type { ApiSchemaFor, ZodFor } from '@aztec/stdlib/schemas';
15
+ import type { ApiSchemaFor } from '@aztec/stdlib/schemas';
16
+ import { zodFor } from '@aztec/stdlib/schemas';
16
17
 
17
18
  import { createHash } from 'crypto';
18
19
  import { createReadStream } from 'fs';
@@ -53,16 +54,18 @@ type TXEForeignCallInput = {
53
54
  inputs: ForeignCallArgs;
54
55
  };
55
56
 
56
- const TXEForeignCallInputSchema = z.object({
57
- // eslint-disable-next-line camelcase
58
- session_id: z.number().int().nonnegative(),
59
- function: z.string() as ZodFor<TXEOracleFunctionName>,
60
- // eslint-disable-next-line camelcase
61
- root_path: z.string(),
62
- // eslint-disable-next-line camelcase
63
- package_name: z.string(),
64
- inputs: ForeignCallArgsSchema,
65
- }) satisfies ZodFor<TXEForeignCallInput>;
57
+ const TXEForeignCallInputSchema = zodFor<TXEForeignCallInput>()(
58
+ z.object({
59
+ // eslint-disable-next-line camelcase
60
+ session_id: z.number().int().nonnegative(),
61
+ function: z.string() as z.ZodType<TXEOracleFunctionName>,
62
+ // eslint-disable-next-line camelcase
63
+ root_path: z.string(),
64
+ // eslint-disable-next-line camelcase
65
+ package_name: z.string(),
66
+ inputs: ForeignCallArgsSchema,
67
+ }),
68
+ );
66
69
 
67
70
  class TXEDispatcher {
68
71
  private protocolContracts!: ProtocolContract[];
@@ -3,9 +3,8 @@ import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { PublicDataWrite } from '@aztec/stdlib/avm';
5
5
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
- import { Body, L2Block } from '@aztec/stdlib/block';
6
+ import type { L2Block } from '@aztec/stdlib/block';
7
7
  import { computePublicDataTreeLeafSlot, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
8
- import { makeAppendOnlyTreeSnapshot } from '@aztec/stdlib/testing';
9
8
  import {
10
9
  MerkleTreeId,
11
10
  type MerkleTreeWriteOperations,
@@ -14,7 +13,7 @@ import {
14
13
  } from '@aztec/stdlib/trees';
15
14
  import { GlobalVariables, TxEffect, TxHash } from '@aztec/stdlib/tx';
16
15
 
17
- import { insertTxEffectIntoWorldTrees, makeTXEBlockHeader } from '../utils/block_creation.js';
16
+ import { insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
18
17
  import type { IAvmExecutionOracle } from './interfaces.js';
19
18
 
20
19
  export class TXEOraclePublicContext implements IAvmExecutionOracle {
@@ -133,11 +132,7 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
133
132
  const txEffect = this.makeTxEffect();
134
133
  await insertTxEffectIntoWorldTrees(txEffect, this.forkedWorldTrees);
135
134
 
136
- const block = new L2Block(
137
- makeAppendOnlyTreeSnapshot(),
138
- await makeTXEBlockHeader(this.forkedWorldTrees, this.globalVariables),
139
- new Body([txEffect]),
140
- );
135
+ const block = await makeTXEBlock(this.forkedWorldTrees, this.globalVariables, [txEffect]);
141
136
 
142
137
  await this.forkedWorldTrees.close();
143
138
 
@@ -48,7 +48,6 @@ import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/st
48
48
  import { AuthWitness } from '@aztec/stdlib/auth-witness';
49
49
  import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
50
50
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
51
- import { Body, L2Block } from '@aztec/stdlib/block';
52
51
  import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
53
52
  import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
54
53
  import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
@@ -59,7 +58,7 @@ import {
59
58
  PublicCallRequest,
60
59
  } from '@aztec/stdlib/kernel';
61
60
  import { ChonkProof } from '@aztec/stdlib/proofs';
62
- import { makeAppendOnlyTreeSnapshot, makeGlobalVariables } from '@aztec/stdlib/testing';
61
+ import { makeGlobalVariables } from '@aztec/stdlib/testing';
63
62
  import { MerkleTreeId } from '@aztec/stdlib/trees';
64
63
  import {
65
64
  CallContext,
@@ -80,11 +79,7 @@ import type { TXEStateMachine } from '../state_machine/index.js';
80
79
  import type { TXEAccountDataProvider } from '../util/txe_account_data_provider.js';
81
80
  import type { TXEContractDataProvider } from '../util/txe_contract_data_provider.js';
82
81
  import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
83
- import {
84
- getSingleTxBlockRequestHash,
85
- insertTxEffectIntoWorldTrees,
86
- makeTXEBlockHeader,
87
- } from '../utils/block_creation.js';
82
+ import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
88
83
  import type { ITxeExecutionOracle } from './interfaces.js';
89
84
 
90
85
  export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
@@ -146,7 +141,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
146
141
  }
147
142
 
148
143
  async txeGetLastTxEffects() {
149
- const block = await this.stateMachine.archiver.getBlock('latest');
144
+ const block = await this.stateMachine.archiver.getL2Block('latest');
150
145
 
151
146
  if (block!.body.txEffects.length != 1) {
152
147
  // Note that calls like env.mine() will result in blocks with no transactions, hitting this
@@ -238,19 +233,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
238
233
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
239
234
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
240
235
 
241
- const block = new L2Block(
242
- makeAppendOnlyTreeSnapshot(),
243
- await makeTXEBlockHeader(
244
- forkedWorldTrees,
245
- makeGlobalVariables(undefined, {
246
- blockNumber,
247
- timestamp: this.nextBlockTimestamp,
248
- version: this.version,
249
- chainId: this.chainId,
250
- }),
251
- ),
252
- new Body([txEffect]),
253
- );
236
+ const globals = makeGlobalVariables(undefined, {
237
+ blockNumber,
238
+ timestamp: this.nextBlockTimestamp,
239
+ version: this.version,
240
+ chainId: this.chainId,
241
+ });
242
+ const block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
254
243
 
255
244
  await forkedWorldTrees.close();
256
245
 
@@ -291,7 +280,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
291
280
 
292
281
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
293
282
 
294
- const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
283
+ const blockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
295
284
 
296
285
  const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
297
286
  const noteCache = new ExecutionNoteCache(protocolNullifier);
@@ -441,13 +430,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
441
430
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
442
431
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
443
432
 
444
- const body = new Body([txEffect]);
445
-
446
- const l2Block = new L2Block(
447
- makeAppendOnlyTreeSnapshot(),
448
- await makeTXEBlockHeader(forkedWorldTrees, globals),
449
- body,
450
- );
433
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
451
434
 
452
435
  await this.stateMachine.handleL2Block(l2Block);
453
436
 
@@ -476,7 +459,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
476
459
 
477
460
  const txContext = new TxContext(this.chainId, this.version, gasSettings);
478
461
 
479
- const anchorBlockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
462
+ const anchorBlockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
480
463
 
481
464
  const calldataHash = await computeCalldataHash(calldata);
482
465
  const calldataHashedValues = new HashedValues(calldata, calldataHash);
@@ -590,13 +573,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
590
573
  const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
591
574
  await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
592
575
 
593
- const body = new Body([txEffect]);
594
-
595
- const l2Block = new L2Block(
596
- makeAppendOnlyTreeSnapshot(),
597
- await makeTXEBlockHeader(forkedWorldTrees, globals),
598
- body,
599
- );
576
+ const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
600
577
 
601
578
  await this.stateMachine.handleL2Block(l2Block);
602
579
 
@@ -632,7 +609,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
632
609
  });
633
610
 
634
611
  try {
635
- const oracle = new UtilityExecutionOracle(call.to, [], [], this.pxeOracleInterface);
612
+ const anchorBlockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
613
+ const oracle = new UtilityExecutionOracle(call.to, [], [], anchorBlockHeader, this.pxeOracleInterface);
636
614
  const acirExecutionResult = await new WASMSimulator()
637
615
  .executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
638
616
  .catch((err: Error) => {
@@ -580,8 +580,8 @@ export class RPCTranslator {
580
580
  return toForeignCallResult([toSingle(new Fr(isRevertible))]);
581
581
  }
582
582
 
583
- async utilityGetUtilityContext() {
584
- const context = await this.handlerAsUtility().utilityGetUtilityContext();
583
+ utilityGetUtilityContext() {
584
+ const context = this.handlerAsUtility().utilityGetUtilityContext();
585
585
 
586
586
  return toForeignCallResult(context.toNoirRepresentation());
587
587
  }
@@ -1,12 +1,21 @@
1
- import { ArchiverStoreHelper, KVArchiverDataStore, type PublishedL2Block } from '@aztec/archiver';
1
+ import { ArchiverStoreHelper, KVArchiverDataStore } from '@aztec/archiver';
2
2
  import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
3
3
  import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
4
4
  import { Fr } from '@aztec/foundation/curves/bn254';
5
5
  import type { EthAddress } from '@aztec/foundation/eth-address';
6
+ import { isDefined } from '@aztec/foundation/types';
6
7
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
7
8
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
8
- import type { L2Block, L2BlockSource, L2Tips, ValidateBlockResult } from '@aztec/stdlib/block';
9
- import type { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
9
+ import {
10
+ CommitteeAttestation,
11
+ L2Block,
12
+ type L2BlockId,
13
+ type L2BlockSource,
14
+ type L2Tips,
15
+ PublishedL2Block,
16
+ type ValidateBlockResult,
17
+ } from '@aztec/stdlib/block';
18
+ import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
10
19
  import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
11
20
  import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
12
21
  import type { BlockHeader } from '@aztec/stdlib/tx';
@@ -20,11 +29,28 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
20
29
  super(new KVArchiverDataStore(db, 9999));
21
30
  }
22
31
 
23
- public override async addBlocks(blocks: PublishedL2Block[]): Promise<boolean> {
24
- const opResults = await Promise.all([
25
- this.store.addLogs(blocks.map(block => block.block)),
26
- this.store.addBlocks(blocks),
27
- ]);
32
+ public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
33
+ if (number === 0) {
34
+ return undefined;
35
+ }
36
+ const publishedBlocks = await this.getPublishedBlocks(number, 1);
37
+ if (publishedBlocks.length === 0) {
38
+ return undefined;
39
+ }
40
+ return publishedBlocks[0].block;
41
+ }
42
+
43
+ public async getBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<L2Block[]> {
44
+ const publishedBlocks = await this.getPublishedBlocks(from, limit, proven);
45
+ return publishedBlocks.map(x => x.block);
46
+ }
47
+
48
+ public override async addCheckpoints(
49
+ checkpoints: PublishedCheckpoint[],
50
+ _result?: ValidateBlockResult,
51
+ ): Promise<boolean> {
52
+ const allBlocks = checkpoints.flatMap(ch => ch.checkpoint.blocks);
53
+ const opResults = await Promise.all([this.store.addLogs(allBlocks), this.store.addCheckpoints(checkpoints)]);
28
54
 
29
55
  return opResults.every(Boolean);
30
56
  }
@@ -34,15 +60,15 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
34
60
  * @returns The number of the latest L2 block processed by the block source implementation.
35
61
  */
36
62
  public getBlockNumber(): Promise<BlockNumber> {
37
- return this.store.getSynchedL2BlockNumber();
63
+ return this.store.getLatestBlockNumber();
38
64
  }
39
65
 
40
66
  /**
41
67
  * Gets the number of the latest L2 block proven seen by the block source implementation.
42
68
  * @returns The number of the latest L2 block proven seen by the block source implementation.
43
69
  */
44
- public getProvenBlockNumber(): Promise<BlockNumber> {
45
- return this.store.getSynchedL2BlockNumber();
70
+ public override getProvenBlockNumber(): Promise<BlockNumber> {
71
+ return this.store.getProvenBlockNumber();
46
72
  }
47
73
 
48
74
  /**
@@ -50,16 +76,55 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
50
76
  * @param number - The block number to return (inclusive).
51
77
  * @returns The requested L2 block.
52
78
  */
53
- public override async getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
79
+ public async getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
54
80
  // If the number provided is -ve, then return the latest block.
55
81
  if (number < 0) {
56
- number = await this.store.getSynchedL2BlockNumber();
82
+ number = await this.store.getLatestBlockNumber();
57
83
  }
58
84
  if (number == 0) {
59
85
  return undefined;
60
86
  }
61
- const blocks = await this.store.getPublishedBlocks(BlockNumber(number), 1);
62
- return blocks.length === 0 ? undefined : blocks[0];
87
+ const publishedBlocks = await this.retrievePublishedBlocks(BlockNumber(number), 1);
88
+ return publishedBlocks.length === 0 ? undefined : publishedBlocks[0];
89
+ }
90
+
91
+ getPublishedBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<PublishedL2Block[]> {
92
+ return this.retrievePublishedBlocks(from, limit, proven);
93
+ }
94
+
95
+ private async retrievePublishedBlocks(
96
+ from: BlockNumber,
97
+ limit: number,
98
+ proven?: boolean,
99
+ ): Promise<PublishedL2Block[]> {
100
+ const checkpoints = await this.store.getRangeOfCheckpoints(CheckpointNumber(from), limit);
101
+ const provenCheckpointNumber = await this.store.getProvenCheckpointNumber();
102
+ const blocks = (
103
+ await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
104
+ ).filter(isDefined);
105
+
106
+ const olbBlocks: PublishedL2Block[] = [];
107
+ for (let i = 0; i < checkpoints.length; i++) {
108
+ const blockForCheckpoint = blocks[i][0];
109
+ const checkpoint = checkpoints[i];
110
+ if (proven === true && checkpoint.checkpointNumber > provenCheckpointNumber) {
111
+ continue;
112
+ }
113
+ const oldCheckpoint = new Checkpoint(
114
+ blockForCheckpoint.archive,
115
+ checkpoint.header,
116
+ [blockForCheckpoint],
117
+ checkpoint.checkpointNumber,
118
+ );
119
+ const oldBlock = L2Block.fromCheckpoint(oldCheckpoint);
120
+ const publishedBlock = new PublishedL2Block(
121
+ oldBlock,
122
+ checkpoint.l1,
123
+ checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
124
+ );
125
+ olbBlocks.push(publishedBlock);
126
+ }
127
+ return olbBlocks;
63
128
  }
64
129
 
65
130
  /**
@@ -67,8 +132,8 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
67
132
  * @param number - The block number to return (inclusive).
68
133
  * @returns The requested L2 block.
69
134
  */
70
- public getBlock(number: number | 'latest'): Promise<L2Block | undefined> {
71
- return this.getPublishedBlock(number != 'latest' ? number : -1).then(block => block?.block);
135
+ public getL2Block(number: BlockNumber | 'latest'): Promise<L2Block | undefined> {
136
+ return this.getPublishedBlock(number != 'latest' ? number : -1).then(b => b?.block);
72
137
  }
73
138
 
74
139
  /**
@@ -78,7 +143,7 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
78
143
  */
79
144
  public async getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined> {
80
145
  if (number === 'latest') {
81
- number = await this.store.getSynchedL2BlockNumber();
146
+ number = await this.store.getLatestBlockNumber();
82
147
  }
83
148
  if (number === 0) {
84
149
  return undefined;
@@ -87,7 +152,7 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
87
152
  return headers.length === 0 ? undefined : headers[0];
88
153
  }
89
154
 
90
- public getBlocks(from: number, limit: number, _proven?: boolean): Promise<L2Block[]> {
155
+ public getBlockRange(from: number, limit: number, _proven?: boolean): Promise<L2Block[]> {
91
156
  return this.getPublishedBlocks(BlockNumber(from), limit).then(blocks => blocks.map(b => b.block));
92
157
  }
93
158
 
@@ -123,8 +188,21 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
123
188
  throw new Error('TXE Archiver does not implement "isEpochComplete"');
124
189
  }
125
190
 
126
- public getL2Tips(): Promise<L2Tips> {
127
- throw new Error('TXE Archiver does not implement "getL2Tips"');
191
+ public async getL2Tips(): Promise<L2Tips> {
192
+ // In TXE there is no possibility of reorgs and no blocks are ever getting proven so we just set 'latest', 'proven'
193
+ // and 'finalized' to the latest block.
194
+ const blockHeader = await this.getBlockHeader('latest');
195
+ if (!blockHeader) {
196
+ throw new Error('L2Tips requested from TXE Archiver but no block header found');
197
+ }
198
+
199
+ const number = blockHeader.globalVariables.blockNumber;
200
+ const hash = (await blockHeader.hash()).toString();
201
+ return {
202
+ latest: { number, hash } as L2BlockId,
203
+ proven: { number, hash } as L2BlockId,
204
+ finalized: { number, hash } as L2BlockId,
205
+ };
128
206
  }
129
207
 
130
208
  public getL1Constants(): Promise<L1RollupConstants> {
@@ -162,4 +240,11 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
162
240
  public override getPendingChainValidationStatus(): Promise<ValidateBlockResult> {
163
241
  return Promise.resolve({ valid: true });
164
242
  }
243
+
244
+ getPublishedBlockByHash(_blockHash: Fr): Promise<PublishedL2Block | undefined> {
245
+ throw new Error('Method not implemented.');
246
+ }
247
+ getPublishedBlockByArchive(_archive: Fr): Promise<PublishedL2Block | undefined> {
248
+ throw new Error('Method not implemented.');
249
+ }
165
250
  }
@@ -79,7 +79,9 @@ export class DummyP2P implements P2P {
79
79
  }
80
80
 
81
81
  public getTxStatus(_txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
82
- throw new Error('DummyP2P does not implement "getTxStatus"');
82
+ // In TXE there is no concept of transactions but we need to implement this because of tagging. We return 'mined'
83
+ // tx status for any tx hash.
84
+ return Promise.resolve('mined');
83
85
  }
84
86
 
85
87
  public iteratePendingTxs(): AsyncIterableIterator<Tx> {
@@ -2,8 +2,9 @@ import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
2
2
  import { TestCircuitVerifier } from '@aztec/bb-prover/test';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
5
- import { SyncDataProvider } from '@aztec/pxe/server';
6
- import { type L2Block, PublishedL2Block } from '@aztec/stdlib/block';
5
+ import { AnchorBlockDataProvider } from '@aztec/pxe/server';
6
+ import { L2Block } from '@aztec/stdlib/block';
7
+ import { L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
7
8
  import type { AztecNode } from '@aztec/stdlib/interfaces/client';
8
9
  import { getPackageVersion } from '@aztec/stdlib/update-checker';
9
10
 
@@ -21,13 +22,13 @@ export class TXEStateMachine {
21
22
  public node: AztecNode,
22
23
  public synchronizer: TXESynchronizer,
23
24
  public archiver: TXEArchiver,
24
- public syncDataProvider: SyncDataProvider,
25
+ public anchorBlockDataProvider: AnchorBlockDataProvider,
25
26
  ) {}
26
27
 
27
28
  public static async create(db: AztecAsyncKVStore) {
28
29
  const archiver = new TXEArchiver(db);
29
30
  const synchronizer = await TXESynchronizer.create();
30
- const syncDataProvider = new SyncDataProvider(db);
31
+ const anchorBlockDataProvider = new AnchorBlockDataProvider(db);
31
32
 
32
33
  const aztecNodeConfig = {} as AztecNodeConfig;
33
34
 
@@ -54,24 +55,24 @@ export class TXEStateMachine {
54
55
  log,
55
56
  );
56
57
 
57
- return new this(node, synchronizer, archiver, syncDataProvider);
58
+ return new this(node, synchronizer, archiver, anchorBlockDataProvider);
58
59
  }
59
60
 
60
61
  public async handleL2Block(block: L2Block) {
62
+ const checkpoint = block.toCheckpoint();
63
+ const publishedCheckpoint = new PublishedCheckpoint(
64
+ checkpoint,
65
+ new L1PublishedData(
66
+ BigInt(block.header.globalVariables.blockNumber),
67
+ block.header.globalVariables.timestamp,
68
+ block.header.globalVariables.blockNumber.toString(),
69
+ ),
70
+ [],
71
+ );
61
72
  await Promise.all([
62
73
  this.synchronizer.handleL2Block(block.toL2Block()),
63
- this.archiver.addBlocks([
64
- PublishedL2Block.fromFields({
65
- block,
66
- l1: {
67
- blockHash: block.header.globalVariables.blockNumber.toString(),
68
- blockNumber: BigInt(block.header.globalVariables.blockNumber),
69
- timestamp: block.header.globalVariables.timestamp,
70
- },
71
- attestations: [],
72
- }),
73
- ]),
74
- this.syncDataProvider.setHeader(block.getBlockHeader()),
74
+ this.archiver.addCheckpoints([publishedCheckpoint], undefined),
75
+ this.anchorBlockDataProvider.setHeader(block.getBlockHeader()),
75
76
  ]);
76
77
  }
77
78
  }
@@ -10,7 +10,8 @@ import {
10
10
  NoteDataProvider,
11
11
  PXEOracleInterface,
12
12
  PrivateEventDataProvider,
13
- TaggingDataProvider,
13
+ RecipientTaggingDataProvider,
14
+ SenderTaggingDataProvider,
14
15
  } from '@aztec/pxe/server';
15
16
  import {
16
17
  ExecutionNoteCache,
@@ -24,11 +25,10 @@ import {
24
25
  import { FunctionSelector } from '@aztec/stdlib/abi';
25
26
  import type { AuthWitness } from '@aztec/stdlib/auth-witness';
26
27
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
27
- import { Body, L2Block } from '@aztec/stdlib/block';
28
28
  import { GasSettings } from '@aztec/stdlib/gas';
29
29
  import { computeProtocolNullifier } from '@aztec/stdlib/hash';
30
30
  import { PrivateContextInputs } from '@aztec/stdlib/kernel';
31
- import { makeAppendOnlyTreeSnapshot, makeGlobalVariables } from '@aztec/stdlib/testing';
31
+ import { makeGlobalVariables } from '@aztec/stdlib/testing';
32
32
  import { CallContext, GlobalVariables, TxContext } from '@aztec/stdlib/tx';
33
33
 
34
34
  import { z } from 'zod';
@@ -41,11 +41,7 @@ import { TXEStateMachine } from './state_machine/index.js';
41
41
  import type { ForeignCallArgs, ForeignCallResult } from './util/encoding.js';
42
42
  import { TXEAccountDataProvider } from './util/txe_account_data_provider.js';
43
43
  import { TXEContractDataProvider } from './util/txe_contract_data_provider.js';
44
- import {
45
- getSingleTxBlockRequestHash,
46
- insertTxEffectIntoWorldTrees,
47
- makeTXEBlockHeader,
48
- } from './utils/block_creation.js';
44
+ import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from './utils/block_creation.js';
49
45
  import { makeTxEffect } from './utils/tx_effect_creation.js';
50
46
 
51
47
  /**
@@ -141,7 +137,8 @@ export class TXESession implements TXESessionStateHandler {
141
137
  const privateEventDataProvider = new PrivateEventDataProvider(store);
142
138
  const contractDataProvider = new TXEContractDataProvider(store);
143
139
  const noteDataProvider = await NoteDataProvider.create(store);
144
- const taggingDataProvider = new TaggingDataProvider(store);
140
+ const senderTaggingDataProvider = new SenderTaggingDataProvider(store);
141
+ const recipientTaggingDataProvider = new RecipientTaggingDataProvider(store);
145
142
  const capsuleDataProvider = new CapsuleDataProvider(store);
146
143
  const keyStore = new KeyStore(store);
147
144
  const accountDataProvider = new TXEAccountDataProvider(store);
@@ -164,8 +161,9 @@ export class TXESession implements TXESessionStateHandler {
164
161
  contractDataProvider,
165
162
  noteDataProvider,
166
163
  capsuleDataProvider,
167
- stateMachine.syncDataProvider,
168
- taggingDataProvider,
164
+ stateMachine.anchorBlockDataProvider,
165
+ senderTaggingDataProvider,
166
+ recipientTaggingDataProvider,
169
167
  addressDataProvider,
170
168
  privateEventDataProvider,
171
169
  );
@@ -358,7 +356,15 @@ export class TXESession implements TXESessionStateHandler {
358
356
  // TODO(#12553): make the synchronizer sync here instead and remove this
359
357
  await this.pxeOracleInterface.syncNoteNullifiers(contractAddress);
360
358
 
361
- this.oracleHandler = new UtilityExecutionOracle(contractAddress, [], [], this.pxeOracleInterface);
359
+ const anchorBlockHeader = await this.stateMachine.anchorBlockDataProvider.getBlockHeader();
360
+
361
+ this.oracleHandler = new UtilityExecutionOracle(
362
+ contractAddress,
363
+ [],
364
+ [],
365
+ anchorBlockHeader,
366
+ this.pxeOracleInterface,
367
+ );
362
368
 
363
369
  this.state = { name: 'UTILITY' };
364
370
  this.logger.debug(`Entered state ${this.state.name}`);
@@ -402,11 +408,7 @@ export class TXESession implements TXESessionStateHandler {
402
408
  const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
403
409
  await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
404
410
 
405
- const block = new L2Block(
406
- makeAppendOnlyTreeSnapshot(),
407
- await makeTXEBlockHeader(forkedWorldTrees, this.state.nextBlockGlobalVariables),
408
- new Body([txEffect]),
409
- );
411
+ const block = await makeTXEBlock(forkedWorldTrees, this.state.nextBlockGlobalVariables, [txEffect]);
410
412
  await this.stateMachine.handleL2Block(block);
411
413
 
412
414
  await forkedWorldTrees.close();