@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.
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -2
- package/dest/oracle/txe_oracle_public_context.d.ts +2 -2
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +3 -5
- package/dest/oracle/txe_oracle_top_level_context.d.ts +1 -1
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +13 -14
- package/dest/rpc_translator.d.ts +3 -3
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +2 -2
- package/dest/state_machine/archiver.d.ts +13 -7
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +83 -15
- package/dest/state_machine/dummy_p2p_client.d.ts +1 -1
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +3 -1
- package/dest/state_machine/index.d.ts +5 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +13 -19
- package/dest/txe_session.d.ts +1 -1
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +10 -9
- package/dest/util/encoding.d.ts +601 -2
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/utils/block_creation.d.ts +16 -2
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +22 -1
- package/package.json +15 -15
- package/src/index.ts +14 -11
- package/src/oracle/txe_oracle_public_context.ts +3 -8
- package/src/oracle/txe_oracle_top_level_context.ts +16 -38
- package/src/rpc_translator.ts +2 -2
- package/src/state_machine/archiver.ts +106 -21
- package/src/state_machine/dummy_p2p_client.ts +3 -1
- package/src/state_machine/index.ts +18 -17
- package/src/txe_session.ts +19 -17
- 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.
|
|
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.
|
|
65
|
-
"@aztec/archiver": "3.0.0-nightly.
|
|
66
|
-
"@aztec/aztec-node": "3.0.0-nightly.
|
|
67
|
-
"@aztec/aztec.js": "3.0.0-nightly.
|
|
68
|
-
"@aztec/bb-prover": "3.0.0-nightly.
|
|
69
|
-
"@aztec/constants": "3.0.0-nightly.
|
|
70
|
-
"@aztec/foundation": "3.0.0-nightly.
|
|
71
|
-
"@aztec/key-store": "3.0.0-nightly.
|
|
72
|
-
"@aztec/kv-store": "3.0.0-nightly.
|
|
73
|
-
"@aztec/protocol-contracts": "3.0.0-nightly.
|
|
74
|
-
"@aztec/pxe": "3.0.0-nightly.
|
|
75
|
-
"@aztec/simulator": "3.0.0-nightly.
|
|
76
|
-
"@aztec/stdlib": "3.0.0-nightly.
|
|
77
|
-
"@aztec/world-state": "3.0.0-nightly.
|
|
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
|
|
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 =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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 {
|
|
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,
|
|
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 =
|
|
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 {
|
|
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.
|
|
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
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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) => {
|
package/src/rpc_translator.ts
CHANGED
|
@@ -580,8 +580,8 @@ export class RPCTranslator {
|
|
|
580
580
|
return toForeignCallResult([toSingle(new Fr(isRevertible))]);
|
|
581
581
|
}
|
|
582
582
|
|
|
583
|
-
|
|
584
|
-
const context =
|
|
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
|
|
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
|
|
9
|
-
|
|
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
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
82
|
+
number = await this.store.getLatestBlockNumber();
|
|
57
83
|
}
|
|
58
84
|
if (number == 0) {
|
|
59
85
|
return undefined;
|
|
60
86
|
}
|
|
61
|
-
const
|
|
62
|
-
return
|
|
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
|
|
71
|
-
return this.getPublishedBlock(number != 'latest' ? number : -1).then(
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
6
|
-
import {
|
|
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
|
|
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
|
|
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,
|
|
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.
|
|
64
|
-
|
|
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
|
}
|
package/src/txe_session.ts
CHANGED
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
NoteDataProvider,
|
|
11
11
|
PXEOracleInterface,
|
|
12
12
|
PrivateEventDataProvider,
|
|
13
|
-
|
|
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 {
|
|
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
|
|
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.
|
|
168
|
-
|
|
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
|
-
|
|
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 =
|
|
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();
|