@aztec/txe 0.0.1-commit.b655e406 → 0.0.1-commit.c7c42ec
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/bin/index.d.ts +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -2
- package/dest/oracle/interfaces.d.ts +9 -6
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +5 -5
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +4 -6
- package/dest/oracle/txe_oracle_top_level_context.d.ts +20 -12
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +95 -63
- package/dest/rpc_translator.d.ts +17 -8
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +69 -20
- package/dest/state_machine/archiver.d.ts +31 -14
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +105 -17
- package/dest/state_machine/dummy_p2p_client.d.ts +4 -2
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +6 -1
- package/dest/state_machine/global_variable_builder.d.ts +5 -3
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +12 -0
- 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 +14 -20
- package/dest/state_machine/mock_epoch_cache.d.ts +6 -5
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +8 -7
- package/dest/state_machine/synchronizer.d.ts +5 -4
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +5 -4
- package/dest/txe_session.d.ts +19 -13
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +55 -41
- package/dest/util/encoding.d.ts +623 -24
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +1 -1
- package/dest/util/expected_failure_error.d.ts +1 -1
- package/dest/util/expected_failure_error.d.ts.map +1 -1
- package/dest/util/txe_account_store.d.ts +10 -0
- package/dest/util/txe_account_store.d.ts.map +1 -0
- package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
- package/dest/util/txe_contract_store.d.ts +12 -0
- package/dest/util/txe_contract_store.d.ts.map +1 -0
- package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
- package/dest/util/txe_public_contract_data_source.d.ts +7 -6
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +11 -11
- package/dest/utils/block_creation.d.ts +19 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +24 -3
- package/dest/utils/tx_effect_creation.d.ts +4 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +6 -6
- package/package.json +18 -17
- package/src/index.ts +15 -12
- package/src/oracle/interfaces.ts +8 -5
- package/src/oracle/txe_oracle_public_context.ts +6 -11
- package/src/oracle/txe_oracle_top_level_context.ts +126 -88
- package/src/rpc_translator.ts +90 -20
- package/src/state_machine/archiver.ts +141 -29
- package/src/state_machine/dummy_p2p_client.ts +9 -2
- package/src/state_machine/global_variable_builder.ts +21 -3
- package/src/state_machine/index.ts +19 -18
- package/src/state_machine/mock_epoch_cache.ts +12 -11
- package/src/state_machine/synchronizer.ts +8 -7
- package/src/txe_session.ts +113 -72
- package/src/util/encoding.ts +1 -1
- package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
- package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
- package/src/util/txe_public_contract_data_source.ts +13 -12
- package/src/utils/block_creation.ts +35 -3
- package/src/utils/tx_effect_creation.ts +8 -7
- package/dest/util/txe_account_data_provider.d.ts +0 -10
- package/dest/util/txe_account_data_provider.d.ts.map +0 -1
- package/dest/util/txe_contract_data_provider.d.ts +0 -12
- package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EpochAndSlot, EpochCacheInterface, EpochCommitteeInfo, SlotTag } from '@aztec/epoch-cache';
|
|
2
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -10,46 +11,46 @@ export class MockEpochCache implements EpochCacheInterface {
|
|
|
10
11
|
return Promise.resolve({
|
|
11
12
|
committee: undefined,
|
|
12
13
|
seed: 0n,
|
|
13
|
-
epoch:
|
|
14
|
+
epoch: EpochNumber.ZERO,
|
|
14
15
|
});
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
getEpochAndSlotNow(): EpochAndSlot {
|
|
18
19
|
return {
|
|
19
|
-
epoch:
|
|
20
|
-
slot:
|
|
20
|
+
epoch: EpochNumber.ZERO,
|
|
21
|
+
slot: SlotNumber(0),
|
|
21
22
|
ts: 0n,
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
getEpochAndSlotInNextL1Slot(): EpochAndSlot & { now: bigint } {
|
|
26
27
|
return {
|
|
27
|
-
epoch:
|
|
28
|
-
slot:
|
|
28
|
+
epoch: EpochNumber.ZERO,
|
|
29
|
+
slot: SlotNumber(0),
|
|
29
30
|
ts: 0n,
|
|
30
31
|
now: 0n,
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
getProposerIndexEncoding(_epoch:
|
|
35
|
+
getProposerIndexEncoding(_epoch: EpochNumber, _slot: SlotNumber, _seed: bigint): `0x${string}` {
|
|
35
36
|
return '0x00';
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
computeProposerIndex(_slot:
|
|
39
|
+
computeProposerIndex(_slot: SlotNumber, _epoch: EpochNumber, _seed: bigint, _size: bigint): bigint {
|
|
39
40
|
return 0n;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
getProposerAttesterAddressInCurrentOrNextSlot(): Promise<{
|
|
43
44
|
currentProposer: EthAddress | undefined;
|
|
44
45
|
nextProposer: EthAddress | undefined;
|
|
45
|
-
currentSlot:
|
|
46
|
-
nextSlot:
|
|
46
|
+
currentSlot: SlotNumber;
|
|
47
|
+
nextSlot: SlotNumber;
|
|
47
48
|
}> {
|
|
48
49
|
return Promise.resolve({
|
|
49
50
|
currentProposer: undefined,
|
|
50
51
|
nextProposer: undefined,
|
|
51
|
-
currentSlot:
|
|
52
|
-
nextSlot:
|
|
52
|
+
currentSlot: SlotNumber(0),
|
|
53
|
+
nextSlot: SlotNumber(0),
|
|
53
54
|
});
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
|
+
import type { L2BlockNew } from '@aztec/stdlib/block';
|
|
4
5
|
import type {
|
|
5
6
|
MerkleTreeReadOperations,
|
|
6
7
|
MerkleTreeWriteOperations,
|
|
@@ -12,7 +13,7 @@ import { NativeWorldStateService } from '@aztec/world-state/native';
|
|
|
12
13
|
|
|
13
14
|
export class TXESynchronizer implements WorldStateSynchronizer {
|
|
14
15
|
// This works when set to 1 as well.
|
|
15
|
-
private blockNumber =
|
|
16
|
+
private blockNumber = BlockNumber.ZERO;
|
|
16
17
|
|
|
17
18
|
constructor(public nativeWorldStateService: NativeWorldStateService) {}
|
|
18
19
|
|
|
@@ -22,7 +23,7 @@ export class TXESynchronizer implements WorldStateSynchronizer {
|
|
|
22
23
|
return new this(nativeWorldStateService);
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
public async handleL2Block(block:
|
|
26
|
+
public async handleL2Block(block: L2BlockNew) {
|
|
26
27
|
await this.nativeWorldStateService.handleL2BlockAndMessages(
|
|
27
28
|
block,
|
|
28
29
|
Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero),
|
|
@@ -37,7 +38,7 @@ export class TXESynchronizer implements WorldStateSynchronizer {
|
|
|
37
38
|
* @param skipThrowIfTargetNotReached - Whether to skip throwing if the target block number is not reached.
|
|
38
39
|
* @returns A promise that resolves with the block number the world state was synced to
|
|
39
40
|
*/
|
|
40
|
-
public syncImmediate(_minBlockNumber?:
|
|
41
|
+
public syncImmediate(_minBlockNumber?: BlockNumber, _skipThrowIfTargetNotReached?: boolean): Promise<BlockNumber> {
|
|
41
42
|
return Promise.resolve(this.blockNumber);
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -48,12 +49,12 @@ export class TXESynchronizer implements WorldStateSynchronizer {
|
|
|
48
49
|
|
|
49
50
|
/** Forks the world state at the given block number, defaulting to the latest one. */
|
|
50
51
|
public fork(block?: number): Promise<MerkleTreeWriteOperations> {
|
|
51
|
-
return this.nativeWorldStateService.fork(block);
|
|
52
|
+
return this.nativeWorldStateService.fork(block ? BlockNumber(block) : undefined);
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
/** Gets a handle that allows reading the state as it was at the given block number. */
|
|
55
56
|
public getSnapshot(blockNumber: number): MerkleTreeReadOperations {
|
|
56
|
-
return this.nativeWorldStateService.getSnapshot(blockNumber);
|
|
57
|
+
return this.nativeWorldStateService.getSnapshot(BlockNumber(blockNumber));
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/** Backups the db to the target path. */
|
package/src/txe_session.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
3
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
4
|
import { KeyStore } from '@aztec/key-store';
|
|
4
5
|
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
5
6
|
import type { ProtocolContract } from '@aztec/protocol-contracts';
|
|
6
7
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
AddressStore,
|
|
9
|
+
CapsuleStore,
|
|
10
|
+
NoteService,
|
|
11
|
+
NoteStore,
|
|
12
|
+
PrivateEventStore,
|
|
13
|
+
RecipientTaggingStore,
|
|
14
|
+
SenderAddressBookStore,
|
|
15
|
+
SenderTaggingStore,
|
|
13
16
|
} from '@aztec/pxe/server';
|
|
14
17
|
import {
|
|
15
18
|
ExecutionNoteCache,
|
|
@@ -23,12 +26,11 @@ import {
|
|
|
23
26
|
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
24
27
|
import type { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
25
28
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
26
|
-
import { Body, L2Block } from '@aztec/stdlib/block';
|
|
27
29
|
import { GasSettings } from '@aztec/stdlib/gas';
|
|
30
|
+
import { computeProtocolNullifier } from '@aztec/stdlib/hash';
|
|
28
31
|
import { PrivateContextInputs } from '@aztec/stdlib/kernel';
|
|
29
|
-
import {
|
|
32
|
+
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
30
33
|
import { CallContext, GlobalVariables, TxContext } from '@aztec/stdlib/tx';
|
|
31
|
-
import type { UInt32 } from '@aztec/stdlib/types';
|
|
32
34
|
|
|
33
35
|
import { z } from 'zod';
|
|
34
36
|
|
|
@@ -38,13 +40,9 @@ import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.
|
|
|
38
40
|
import { RPCTranslator } from './rpc_translator.js';
|
|
39
41
|
import { TXEStateMachine } from './state_machine/index.js';
|
|
40
42
|
import type { ForeignCallArgs, ForeignCallResult } from './util/encoding.js';
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
getSingleTxBlockRequestHash,
|
|
45
|
-
insertTxEffectIntoWorldTrees,
|
|
46
|
-
makeTXEBlockHeader,
|
|
47
|
-
} from './utils/block_creation.js';
|
|
43
|
+
import { TXEAccountStore } from './util/txe_account_store.js';
|
|
44
|
+
import { TXEContractStore } from './util/txe_contract_store.js';
|
|
45
|
+
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from './utils/block_creation.js';
|
|
48
46
|
import { makeTxEffect } from './utils/tx_effect_creation.js';
|
|
49
47
|
|
|
50
48
|
/**
|
|
@@ -66,7 +64,7 @@ type SessionState =
|
|
|
66
64
|
| {
|
|
67
65
|
name: 'PRIVATE';
|
|
68
66
|
nextBlockGlobalVariables: GlobalVariables;
|
|
69
|
-
|
|
67
|
+
protocolNullifier: Fr;
|
|
70
68
|
noteCache: ExecutionNoteCache;
|
|
71
69
|
taggingIndexCache: ExecutionTaggingIndexCache;
|
|
72
70
|
}
|
|
@@ -101,11 +99,11 @@ export type TXEOracleFunctionName = Exclude<
|
|
|
101
99
|
export interface TXESessionStateHandler {
|
|
102
100
|
enterTopLevelState(): Promise<void>;
|
|
103
101
|
enterPublicState(contractAddress?: AztecAddress): Promise<void>;
|
|
104
|
-
enterPrivateState(contractAddress?: AztecAddress, anchorBlockNumber?:
|
|
102
|
+
enterPrivateState(contractAddress?: AztecAddress, anchorBlockNumber?: BlockNumber): Promise<PrivateContextInputs>;
|
|
105
103
|
enterUtilityState(contractAddress?: AztecAddress): Promise<void>;
|
|
106
104
|
}
|
|
107
105
|
|
|
108
|
-
const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
|
|
106
|
+
export const DEFAULT_ADDRESS = AztecAddress.fromNumber(42);
|
|
109
107
|
|
|
110
108
|
/**
|
|
111
109
|
* A `TXESession` corresponds to a Noir `#[test]` function, and handles all of its oracle calls, stores test-specific
|
|
@@ -123,32 +121,39 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
123
121
|
| IPrivateExecutionOracle
|
|
124
122
|
| IAvmExecutionOracle
|
|
125
123
|
| ITxeExecutionOracle,
|
|
126
|
-
private
|
|
124
|
+
private contractStore: TXEContractStore,
|
|
125
|
+
private noteStore: NoteStore,
|
|
127
126
|
private keyStore: KeyStore,
|
|
128
|
-
private
|
|
129
|
-
private
|
|
127
|
+
private addressStore: AddressStore,
|
|
128
|
+
private accountStore: TXEAccountStore,
|
|
129
|
+
private senderTaggingStore: SenderTaggingStore,
|
|
130
|
+
private recipientTaggingStore: RecipientTaggingStore,
|
|
131
|
+
private senderAddressBookStore: SenderAddressBookStore,
|
|
132
|
+
private capsuleStore: CapsuleStore,
|
|
133
|
+
private privateEventStore: PrivateEventStore,
|
|
130
134
|
private chainId: Fr,
|
|
131
135
|
private version: Fr,
|
|
132
136
|
private nextBlockTimestamp: bigint,
|
|
133
|
-
private pxeOracleInterface: PXEOracleInterface,
|
|
134
137
|
) {}
|
|
135
138
|
|
|
136
139
|
static async init(protocolContracts: ProtocolContract[]) {
|
|
137
140
|
const store = await openTmpStore('txe-session');
|
|
138
141
|
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
const
|
|
142
|
+
const addressStore = new AddressStore(store);
|
|
143
|
+
const privateEventStore = new PrivateEventStore(store);
|
|
144
|
+
const contractStore = new TXEContractStore(store);
|
|
145
|
+
const noteStore = await NoteStore.create(store);
|
|
146
|
+
const senderTaggingStore = new SenderTaggingStore(store);
|
|
147
|
+
const recipientTaggingStore = new RecipientTaggingStore(store);
|
|
148
|
+
const senderAddressBookStore = new SenderAddressBookStore(store);
|
|
149
|
+
const capsuleStore = new CapsuleStore(store);
|
|
145
150
|
const keyStore = new KeyStore(store);
|
|
146
|
-
const
|
|
151
|
+
const accountStore = new TXEAccountStore(store);
|
|
147
152
|
|
|
148
153
|
// Register protocol contracts.
|
|
149
154
|
for (const { contractClass, instance, artifact } of protocolContracts) {
|
|
150
|
-
await
|
|
151
|
-
await
|
|
155
|
+
await contractStore.addContractArtifact(contractClass.id, artifact);
|
|
156
|
+
await contractStore.addContractInstance(instance);
|
|
152
157
|
}
|
|
153
158
|
|
|
154
159
|
const stateMachine = await TXEStateMachine.create(store);
|
|
@@ -157,25 +162,18 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
157
162
|
const version = new Fr(await stateMachine.node.getVersion());
|
|
158
163
|
const chainId = new Fr(await stateMachine.node.getChainId());
|
|
159
164
|
|
|
160
|
-
const pxeOracleInterface = new PXEOracleInterface(
|
|
161
|
-
stateMachine.node,
|
|
162
|
-
keyStore,
|
|
163
|
-
contractDataProvider,
|
|
164
|
-
noteDataProvider,
|
|
165
|
-
capsuleDataProvider,
|
|
166
|
-
stateMachine.syncDataProvider,
|
|
167
|
-
taggingDataProvider,
|
|
168
|
-
addressDataProvider,
|
|
169
|
-
privateEventDataProvider,
|
|
170
|
-
);
|
|
171
|
-
|
|
172
165
|
const topLevelOracleHandler = new TXEOracleTopLevelContext(
|
|
173
166
|
stateMachine,
|
|
174
|
-
|
|
167
|
+
contractStore,
|
|
168
|
+
noteStore,
|
|
175
169
|
keyStore,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
170
|
+
addressStore,
|
|
171
|
+
accountStore,
|
|
172
|
+
senderTaggingStore,
|
|
173
|
+
recipientTaggingStore,
|
|
174
|
+
senderAddressBookStore,
|
|
175
|
+
capsuleStore,
|
|
176
|
+
privateEventStore,
|
|
179
177
|
nextBlockTimestamp,
|
|
180
178
|
version,
|
|
181
179
|
chainId,
|
|
@@ -187,14 +185,19 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
187
185
|
createLogger('txe:session'),
|
|
188
186
|
stateMachine,
|
|
189
187
|
topLevelOracleHandler,
|
|
190
|
-
|
|
188
|
+
contractStore,
|
|
189
|
+
noteStore,
|
|
191
190
|
keyStore,
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
addressStore,
|
|
192
|
+
accountStore,
|
|
193
|
+
senderTaggingStore,
|
|
194
|
+
recipientTaggingStore,
|
|
195
|
+
senderAddressBookStore,
|
|
196
|
+
capsuleStore,
|
|
197
|
+
privateEventStore,
|
|
194
198
|
version,
|
|
195
199
|
chainId,
|
|
196
200
|
nextBlockTimestamp,
|
|
197
|
-
pxeOracleInterface,
|
|
198
201
|
);
|
|
199
202
|
}
|
|
200
203
|
|
|
@@ -253,11 +256,16 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
253
256
|
|
|
254
257
|
this.oracleHandler = new TXEOracleTopLevelContext(
|
|
255
258
|
this.stateMachine,
|
|
256
|
-
this.
|
|
259
|
+
this.contractStore,
|
|
260
|
+
this.noteStore,
|
|
257
261
|
this.keyStore,
|
|
258
|
-
this.
|
|
259
|
-
this.
|
|
260
|
-
this.
|
|
262
|
+
this.addressStore,
|
|
263
|
+
this.accountStore,
|
|
264
|
+
this.senderTaggingStore,
|
|
265
|
+
this.recipientTaggingStore,
|
|
266
|
+
this.senderAddressBookStore,
|
|
267
|
+
this.capsuleStore,
|
|
268
|
+
this.privateEventStore,
|
|
261
269
|
this.nextBlockTimestamp,
|
|
262
270
|
this.version,
|
|
263
271
|
this.chainId,
|
|
@@ -270,7 +278,7 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
270
278
|
|
|
271
279
|
async enterPrivateState(
|
|
272
280
|
contractAddress: AztecAddress = DEFAULT_ADDRESS,
|
|
273
|
-
anchorBlockNumber?:
|
|
281
|
+
anchorBlockNumber?: BlockNumber,
|
|
274
282
|
): Promise<PrivateContextInputs> {
|
|
275
283
|
this.exitTopLevelState();
|
|
276
284
|
|
|
@@ -279,7 +287,11 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
279
287
|
// we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
|
|
280
288
|
// be removed from the database.
|
|
281
289
|
// TODO(#12553): make the synchronizer sync here instead and remove this
|
|
282
|
-
await
|
|
290
|
+
await new NoteService(
|
|
291
|
+
this.noteStore,
|
|
292
|
+
this.stateMachine.node,
|
|
293
|
+
this.stateMachine.anchorBlockStore,
|
|
294
|
+
).syncNoteNullifiers(contractAddress);
|
|
283
295
|
|
|
284
296
|
// Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
|
|
285
297
|
// build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
|
|
@@ -288,14 +300,15 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
288
300
|
const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
|
|
289
301
|
|
|
290
302
|
const nextBlockGlobalVariables = makeGlobalVariables(undefined, {
|
|
291
|
-
blockNumber: latestBlock!.globalVariables.blockNumber + 1,
|
|
303
|
+
blockNumber: BlockNumber(latestBlock!.globalVariables.blockNumber + 1),
|
|
292
304
|
timestamp: this.nextBlockTimestamp,
|
|
293
305
|
version: this.version,
|
|
294
306
|
chainId: this.chainId,
|
|
295
307
|
});
|
|
296
308
|
|
|
297
309
|
const txRequestHash = getSingleTxBlockRequestHash(nextBlockGlobalVariables.blockNumber);
|
|
298
|
-
const
|
|
310
|
+
const protocolNullifier = await computeProtocolNullifier(txRequestHash);
|
|
311
|
+
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
299
312
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
300
313
|
|
|
301
314
|
this.oracleHandler = new PrivateExecutionOracle(
|
|
@@ -308,7 +321,17 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
308
321
|
new HashedValuesCache(),
|
|
309
322
|
noteCache,
|
|
310
323
|
taggingIndexCache,
|
|
311
|
-
this.
|
|
324
|
+
this.contractStore,
|
|
325
|
+
this.noteStore,
|
|
326
|
+
this.keyStore,
|
|
327
|
+
this.addressStore,
|
|
328
|
+
this.stateMachine.node,
|
|
329
|
+
this.stateMachine.anchorBlockStore,
|
|
330
|
+
this.senderTaggingStore,
|
|
331
|
+
this.recipientTaggingStore,
|
|
332
|
+
this.senderAddressBookStore,
|
|
333
|
+
this.capsuleStore,
|
|
334
|
+
this.privateEventStore,
|
|
312
335
|
);
|
|
313
336
|
|
|
314
337
|
// We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
|
|
@@ -316,7 +339,7 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
316
339
|
// difference resides in that the simulator has all information needed in order to run the simulation, while ours
|
|
317
340
|
// will be ongoing as the different oracles will be invoked from the Noir test, until eventually the private
|
|
318
341
|
// execution finishes.
|
|
319
|
-
this.state = { name: 'PRIVATE', nextBlockGlobalVariables,
|
|
342
|
+
this.state = { name: 'PRIVATE', nextBlockGlobalVariables, protocolNullifier, noteCache, taggingIndexCache };
|
|
320
343
|
this.logger.debug(`Entered state ${this.state.name}`);
|
|
321
344
|
|
|
322
345
|
return (this.oracleHandler as PrivateExecutionOracle).getPrivateContextInputs();
|
|
@@ -329,7 +352,7 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
329
352
|
// the test. The block therefore gets the *next* block number and timestamp.
|
|
330
353
|
const latestBlockNumber = (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.blockNumber;
|
|
331
354
|
const globalVariables = makeGlobalVariables(undefined, {
|
|
332
|
-
blockNumber: latestBlockNumber + 1,
|
|
355
|
+
blockNumber: BlockNumber(latestBlockNumber + 1),
|
|
333
356
|
timestamp: this.nextBlockTimestamp,
|
|
334
357
|
version: this.version,
|
|
335
358
|
chainId: this.chainId,
|
|
@@ -354,9 +377,30 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
354
377
|
// we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
|
|
355
378
|
// be removed from the database.
|
|
356
379
|
// TODO(#12553): make the synchronizer sync here instead and remove this
|
|
357
|
-
await
|
|
380
|
+
await new NoteService(
|
|
381
|
+
this.noteStore,
|
|
382
|
+
this.stateMachine.node,
|
|
383
|
+
this.stateMachine.anchorBlockStore,
|
|
384
|
+
).syncNoteNullifiers(contractAddress);
|
|
385
|
+
|
|
386
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
358
387
|
|
|
359
|
-
this.oracleHandler = new UtilityExecutionOracle(
|
|
388
|
+
this.oracleHandler = new UtilityExecutionOracle(
|
|
389
|
+
contractAddress,
|
|
390
|
+
[],
|
|
391
|
+
[],
|
|
392
|
+
anchorBlockHeader,
|
|
393
|
+
this.contractStore,
|
|
394
|
+
this.noteStore,
|
|
395
|
+
this.keyStore,
|
|
396
|
+
this.addressStore,
|
|
397
|
+
this.stateMachine.node,
|
|
398
|
+
this.stateMachine.anchorBlockStore,
|
|
399
|
+
this.recipientTaggingStore,
|
|
400
|
+
this.senderAddressBookStore,
|
|
401
|
+
this.capsuleStore,
|
|
402
|
+
this.privateEventStore,
|
|
403
|
+
);
|
|
360
404
|
|
|
361
405
|
this.state = { name: 'UTILITY' };
|
|
362
406
|
this.logger.debug(`Entered state ${this.state.name}`);
|
|
@@ -390,9 +434,10 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
390
434
|
|
|
391
435
|
// We rely on the note cache to determine the effects of the transaction. This is incomplete as it doesn't private
|
|
392
436
|
// logs (other effects like enqueued public calls don't need to be considered since those are not allowed).
|
|
437
|
+
|
|
393
438
|
const txEffect = await makeTxEffect(
|
|
394
439
|
this.state.noteCache,
|
|
395
|
-
this.state.
|
|
440
|
+
this.state.protocolNullifier,
|
|
396
441
|
this.state.nextBlockGlobalVariables.blockNumber,
|
|
397
442
|
);
|
|
398
443
|
|
|
@@ -400,11 +445,7 @@ export class TXESession implements TXESessionStateHandler {
|
|
|
400
445
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
401
446
|
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
402
447
|
|
|
403
|
-
const block =
|
|
404
|
-
makeAppendOnlyTreeSnapshot(),
|
|
405
|
-
await makeTXEBlockHeader(forkedWorldTrees, this.state.nextBlockGlobalVariables),
|
|
406
|
-
new Body([txEffect]),
|
|
407
|
-
);
|
|
448
|
+
const block = await makeTXEBlock(forkedWorldTrees, this.state.nextBlockGlobalVariables, [txEffect]);
|
|
408
449
|
await this.stateMachine.handleL2Block(block);
|
|
409
450
|
|
|
410
451
|
await forkedWorldTrees.close();
|
package/src/util/encoding.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
1
2
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { hexToBuffer } from '@aztec/foundation/string';
|
|
4
4
|
import { type ContractArtifact, ContractArtifactSchema } from '@aztec/stdlib/abi';
|
|
5
5
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -2,7 +2,7 @@ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
|
2
2
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
3
|
import { CompleteAddress } from '@aztec/stdlib/contract';
|
|
4
4
|
|
|
5
|
-
export class
|
|
5
|
+
export class TXEAccountStore {
|
|
6
6
|
#accounts: AztecAsyncMap<string, Buffer>;
|
|
7
7
|
|
|
8
8
|
constructor(store: AztecAsyncKVStore) {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { ContractArtifact } from '@aztec/aztec.js/abi';
|
|
2
2
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
3
|
-
import {
|
|
3
|
+
import { ContractStore } from '@aztec/pxe/server';
|
|
4
4
|
|
|
5
5
|
export type ContractArtifactWithHash = ContractArtifact & { artifactHash: Fr };
|
|
6
6
|
|
|
7
7
|
/*
|
|
8
|
-
* A contract
|
|
8
|
+
* A contract store that stores contract artifacts with their hashes. Since
|
|
9
9
|
* TXE typically deploys the same contract again and again for multiple tests, caching
|
|
10
10
|
* the *very* expensive artifact hash computation improves testing speed significantly.
|
|
11
11
|
*/
|
|
12
|
-
export class
|
|
12
|
+
export class TXEContractStore extends ContractStore {
|
|
13
13
|
#artifactHashes: Map<string, Buffer> = new Map();
|
|
14
14
|
|
|
15
15
|
public override async addContractArtifact(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
+
import type { ContractStore } from '@aztec/pxe/server';
|
|
3
4
|
import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
4
5
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
6
|
import {
|
|
@@ -14,20 +15,20 @@ import {
|
|
|
14
15
|
export class TXEPublicContractDataSource implements ContractDataSource {
|
|
15
16
|
#privateFunctionsRoot: Map<string, Buffer> = new Map();
|
|
16
17
|
constructor(
|
|
17
|
-
private blockNumber:
|
|
18
|
-
private
|
|
18
|
+
private blockNumber: BlockNumber,
|
|
19
|
+
private contractStore: ContractStore,
|
|
19
20
|
) {}
|
|
20
21
|
|
|
21
|
-
getBlockNumber(): Promise<
|
|
22
|
+
getBlockNumber(): Promise<BlockNumber> {
|
|
22
23
|
return Promise.resolve(this.blockNumber);
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
async getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
|
|
26
|
-
const contractClass = await this.
|
|
27
|
+
const contractClass = await this.contractStore.getContractClass(id);
|
|
27
28
|
if (!contractClass) {
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
30
|
-
const artifact = await this.
|
|
31
|
+
const artifact = await this.contractStore.getContractArtifact(id);
|
|
31
32
|
if (!artifact) {
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
@@ -57,12 +58,12 @@ export class TXEPublicContractDataSource implements ContractDataSource {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
async getBytecodeCommitment(id: Fr): Promise<Fr | undefined> {
|
|
60
|
-
const contractClass = await this.
|
|
61
|
+
const contractClass = await this.contractStore.getContractClass(id);
|
|
61
62
|
return contractClass && computePublicBytecodeCommitment(contractClass.packedBytecode);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
async getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
65
|
-
const instance = await this.
|
|
66
|
+
const instance = await this.contractStore.getContractInstance(address);
|
|
66
67
|
return instance && { ...instance, address };
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -71,12 +72,12 @@ export class TXEPublicContractDataSource implements ContractDataSource {
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
async getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
|
|
74
|
-
const instance = await this.
|
|
75
|
-
return instance && this.
|
|
75
|
+
const instance = await this.contractStore.getContractInstance(address);
|
|
76
|
+
return instance && this.contractStore.getContractArtifact(instance.currentContractClassId);
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
|
|
79
|
-
return await this.
|
|
80
|
+
return await this.contractStore.getDebugFunctionName(address, selector);
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
registerContractFunctionSignatures(_signatures: []): Promise<void> {
|
|
@@ -4,9 +4,10 @@ import {
|
|
|
4
4
|
NULLIFIER_SUBTREE_HEIGHT,
|
|
5
5
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
6
6
|
} from '@aztec/constants';
|
|
7
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
7
8
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
8
|
-
import { Fr } from '@aztec/foundation/
|
|
9
|
-
import { L2BlockHeader } from '@aztec/stdlib/block';
|
|
9
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
10
|
+
import { Body, L2Block, L2BlockHeader } from '@aztec/stdlib/block';
|
|
10
11
|
import { makeContentCommitment } from '@aztec/stdlib/testing';
|
|
11
12
|
import { AppendOnlyTreeSnapshot, MerkleTreeId, type MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
|
|
12
13
|
import { GlobalVariables, TxEffect } from '@aztec/stdlib/tx';
|
|
@@ -16,7 +17,7 @@ import { GlobalVariables, TxEffect } from '@aztec/stdlib/tx';
|
|
|
16
17
|
* @param blockNumber The number for the block in which there is a single transaction.
|
|
17
18
|
* @returns The transaction request hash.
|
|
18
19
|
*/
|
|
19
|
-
export function getSingleTxBlockRequestHash(blockNumber:
|
|
20
|
+
export function getSingleTxBlockRequestHash(blockNumber: BlockNumber): Fr {
|
|
20
21
|
return new Fr(blockNumber + 9999); // Why does this need to be a high number? Why do small numbered nullifiers already exist?
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -58,5 +59,36 @@ export async function makeTXEBlockHeader(
|
|
|
58
59
|
Fr.ZERO,
|
|
59
60
|
Fr.ZERO,
|
|
60
61
|
Fr.ZERO,
|
|
62
|
+
Fr.ZERO,
|
|
61
63
|
);
|
|
62
64
|
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Creates an L2Block with proper archive chaining.
|
|
68
|
+
* This function:
|
|
69
|
+
* 1. Gets the current archive state as lastArchive for the header
|
|
70
|
+
* 2. Creates the block header
|
|
71
|
+
* 3. Updates the archive tree with the header hash
|
|
72
|
+
* 4. Gets the new archive state for the block's archive
|
|
73
|
+
*
|
|
74
|
+
* @param worldTrees - The world trees to read/write from
|
|
75
|
+
* @param globalVariables - Global variables for the block
|
|
76
|
+
* @param txEffects - Transaction effects to include in the block
|
|
77
|
+
* @returns The created L2Block with proper archive chaining
|
|
78
|
+
*/
|
|
79
|
+
export async function makeTXEBlock(
|
|
80
|
+
worldTrees: MerkleTreeWriteOperations,
|
|
81
|
+
globalVariables: GlobalVariables,
|
|
82
|
+
txEffects: TxEffect[],
|
|
83
|
+
): Promise<L2Block> {
|
|
84
|
+
const header = await makeTXEBlockHeader(worldTrees, globalVariables);
|
|
85
|
+
|
|
86
|
+
// Update the archive tree with this block's header hash
|
|
87
|
+
await worldTrees.updateArchive(header.toBlockHeader());
|
|
88
|
+
|
|
89
|
+
// Get the new archive state after updating
|
|
90
|
+
const newArchiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
|
|
91
|
+
const newArchive = new AppendOnlyTreeSnapshot(new Fr(newArchiveInfo.root), Number(newArchiveInfo.size));
|
|
92
|
+
|
|
93
|
+
return new L2Block(newArchive, header, new Body(txEffects));
|
|
94
|
+
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
3
|
import type { ExecutionNoteCache } from '@aztec/pxe/simulator';
|
|
3
4
|
import { computeNoteHashNonce, computeUniqueNoteHash, siloNoteHash } from '@aztec/stdlib/hash';
|
|
4
5
|
import { TxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
5
6
|
|
|
6
7
|
export async function makeTxEffect(
|
|
7
8
|
noteCache: ExecutionNoteCache,
|
|
8
|
-
|
|
9
|
-
txBlockNumber:
|
|
9
|
+
protocolNullifier: Fr,
|
|
10
|
+
txBlockNumber: BlockNumber,
|
|
10
11
|
): Promise<TxEffect> {
|
|
11
12
|
const txEffect = TxEffect.empty();
|
|
12
13
|
|
|
13
|
-
const {
|
|
14
|
-
const nonceGenerator =
|
|
14
|
+
const { usedProtocolNullifierForNonces } = noteCache.finish();
|
|
15
|
+
const nonceGenerator = usedProtocolNullifierForNonces ? protocolNullifier : noteCache.getAllNullifiers()[0];
|
|
15
16
|
|
|
16
17
|
txEffect.noteHashes = await Promise.all(
|
|
17
18
|
noteCache
|
|
@@ -27,8 +28,8 @@ export async function makeTxEffect(
|
|
|
27
28
|
// Nullifiers are already siloed
|
|
28
29
|
txEffect.nullifiers = noteCache.getAllNullifiers();
|
|
29
30
|
|
|
30
|
-
if (
|
|
31
|
-
txEffect.nullifiers.unshift(
|
|
31
|
+
if (usedProtocolNullifierForNonces) {
|
|
32
|
+
txEffect.nullifiers.unshift(protocolNullifier);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
txEffect.txHash = new TxHash(new Fr(txBlockNumber));
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
2
|
-
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
|
-
import { CompleteAddress } from '@aztec/stdlib/contract';
|
|
4
|
-
export declare class TXEAccountDataProvider {
|
|
5
|
-
#private;
|
|
6
|
-
constructor(store: AztecAsyncKVStore);
|
|
7
|
-
getAccount(key: AztecAddress): Promise<CompleteAddress>;
|
|
8
|
-
setAccount(key: AztecAddress, value: CompleteAddress): Promise<void>;
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=txe_account_data_provider.d.ts.map
|