@aztec/sequencer-client 0.1.0-alpha46 → 0.1.0-alpha48

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 (50) hide show
  1. package/.tsbuildinfo +1 -1
  2. package/dest/block_builder/solo_block_builder.test.d.ts.map +1 -1
  3. package/dest/block_builder/solo_block_builder.test.js +3 -3
  4. package/dest/global_variable_builder/global_builder.d.ts +13 -2
  5. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  6. package/dest/global_variable_builder/global_builder.js +17 -5
  7. package/dest/global_variable_builder/index.d.ts +2 -1
  8. package/dest/global_variable_builder/index.d.ts.map +1 -1
  9. package/dest/global_variable_builder/index.js +4 -4
  10. package/dest/global_variable_builder/viem-reader.d.ts +2 -0
  11. package/dest/global_variable_builder/viem-reader.d.ts.map +1 -1
  12. package/dest/global_variable_builder/viem-reader.js +7 -1
  13. package/dest/index.d.ts +2 -0
  14. package/dest/index.d.ts.map +1 -1
  15. package/dest/index.js +4 -1
  16. package/dest/publisher/l1-publisher.d.ts +12 -6
  17. package/dest/publisher/l1-publisher.d.ts.map +1 -1
  18. package/dest/publisher/l1-publisher.js +3 -3
  19. package/dest/publisher/viem-tx-sender.d.ts +3 -3
  20. package/dest/publisher/viem-tx-sender.d.ts.map +1 -1
  21. package/dest/publisher/viem-tx-sender.js +10 -7
  22. package/dest/sequencer/processed_tx.d.ts +13 -0
  23. package/dest/sequencer/processed_tx.d.ts.map +1 -1
  24. package/dest/sequencer/processed_tx.js +1 -1
  25. package/dest/sequencer/public_processor.d.ts +2 -2
  26. package/dest/sequencer/public_processor.d.ts.map +1 -1
  27. package/dest/sequencer/public_processor.js +11 -6
  28. package/dest/sequencer/public_processor.test.js +9 -7
  29. package/dest/sequencer/sequencer.d.ts +2 -2
  30. package/dest/sequencer/sequencer.d.ts.map +1 -1
  31. package/dest/sequencer/sequencer.js +11 -10
  32. package/dest/simulator/index.d.ts +1 -0
  33. package/dest/simulator/index.d.ts.map +1 -1
  34. package/dest/simulator/index.js +2 -2
  35. package/dest/simulator/public_executor.d.ts.map +1 -1
  36. package/dest/simulator/public_executor.js +5 -5
  37. package/package.json +10 -10
  38. package/src/block_builder/solo_block_builder.test.ts +2 -1
  39. package/src/global_variable_builder/global_builder.ts +30 -4
  40. package/src/global_variable_builder/index.ts +4 -3
  41. package/src/global_variable_builder/viem-reader.ts +8 -0
  42. package/src/index.ts +4 -0
  43. package/src/publisher/l1-publisher.ts +15 -13
  44. package/src/publisher/viem-tx-sender.ts +10 -7
  45. package/src/sequencer/processed_tx.ts +14 -0
  46. package/src/sequencer/public_processor.test.ts +16 -7
  47. package/src/sequencer/public_processor.ts +12 -8
  48. package/src/sequencer/sequencer.ts +10 -20
  49. package/src/simulator/index.ts +2 -0
  50. package/src/simulator/public_executor.ts +5 -5
@@ -1,6 +1,6 @@
1
1
  import { createDebugLogger } from '@aztec/foundation/log';
2
2
  import { InterruptableSleep } from '@aztec/foundation/sleep';
3
- import { ContractDataAndBytecode, L2Block } from '@aztec/types';
3
+ import { ExtendedContractData, L2Block } from '@aztec/types';
4
4
 
5
5
  import { L2BlockReceiver } from '../receiver.js';
6
6
  import { PublisherConfig } from './config.js';
@@ -31,16 +31,22 @@ export interface L1PublisherTxSender {
31
31
  sendProcessTx(encodedData: L1ProcessArgs): Promise<string | undefined>;
32
32
 
33
33
  /**
34
- * Sends a tx to the public contract data emitter contract with contract deployment data such as bytecode. Returns once the tx has been mined.
35
- * @param l2BlockNum - Number of the L2 block that owns this public contract data.
34
+ * Sends a tx to the contract deployment emitter contract with contract deployment data such as bytecode. Returns once the tx has been mined.
35
+ * @param l2BlockNum - Number of the L2 block that owns this encrypted logs.
36
36
  * @param l2BlockHash - The hash of the block corresponding to this data.
37
- * @param contractData - Data to publish.
37
+ * @param partialAddresses - The partial addresses of the deployed contract
38
+ * @param publicKeys - The public keys of the deployed contract
39
+ * @param newExtendedContractData - Data to publish.
38
40
  * @returns The hash of the mined tx.
41
+ * @remarks Partial addresses, public keys and contract data has to be in the same order.
42
+ * @remarks See the link bellow for more info on partial address and public key:
43
+ * https://github.com/AztecProtocol/aztec-packages/blob/master/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys
44
+ * TODO: replace the link above with the link to deployed docs
39
45
  */
40
46
  sendEmitContractDeploymentTx(
41
47
  l2BlockNum: number,
42
48
  l2BlockHash: Buffer,
43
- contractData: ContractDataAndBytecode[],
49
+ newExtendedContractData: ExtendedContractData[],
44
50
  ): Promise<(string | undefined)[]>;
45
51
 
46
52
  /**
@@ -139,12 +145,8 @@ export class L1Publisher implements L2BlockReceiver {
139
145
  * @param contractData - The new contract data to publish.
140
146
  * @returns True once the tx has been confirmed and is successful, false on revert or interrupt, blocks otherwise.
141
147
  */
142
- public async processNewContractData(
143
- l2BlockNum: number,
144
- l2BlockHash: Buffer,
145
- contractData: ContractDataAndBytecode[],
146
- ) {
147
- let _contractData: ContractDataAndBytecode[] = [];
148
+ public async processNewContractData(l2BlockNum: number, l2BlockHash: Buffer, contractData: ExtendedContractData[]) {
149
+ let _contractData: ExtendedContractData[] = [];
148
150
  while (!this.interrupted) {
149
151
  if (!(await this.checkFeeDistributorBalance())) {
150
152
  this.log(`Fee distributor ETH balance too low, awaiting top up...`);
@@ -217,11 +219,11 @@ export class L1Publisher implements L2BlockReceiver {
217
219
  private async sendEmitNewContractDataTx(
218
220
  l2BlockNum: number,
219
221
  l2BlockHash: Buffer,
220
- contractData: ContractDataAndBytecode[],
222
+ newExtendedContractData: ExtendedContractData[],
221
223
  ) {
222
224
  while (!this.interrupted) {
223
225
  try {
224
- return await this.txSender.sendEmitContractDeploymentTx(l2BlockNum, l2BlockHash, contractData);
226
+ return await this.txSender.sendEmitContractDeploymentTx(l2BlockNum, l2BlockHash, newExtendedContractData);
225
227
  } catch (err) {
226
228
  this.log.error(`Error sending contract data to L1`, err);
227
229
  await this.sleepOrInterrupted();
@@ -1,7 +1,7 @@
1
1
  import { createEthereumChain } from '@aztec/ethereum';
2
2
  import { createDebugLogger } from '@aztec/foundation/log';
3
3
  import { ContractDeploymentEmitterAbi, RollupAbi } from '@aztec/l1-artifacts';
4
- import { ContractDataAndBytecode } from '@aztec/types';
4
+ import { ExtendedContractData } from '@aztec/types';
5
5
 
6
6
  import {
7
7
  GetContractReturnType,
@@ -120,22 +120,25 @@ export class ViemTxSender implements L1PublisherTxSender {
120
120
  * Sends a tx to the contract deployment emitter contract with contract deployment data such as bytecode. Returns once the tx has been mined.
121
121
  * @param l2BlockNum - Number of the L2 block that owns this encrypted logs.
122
122
  * @param l2BlockHash - The hash of the block corresponding to this data.
123
- * @param newContractDataAndBytecode - Data to publish.
123
+ * @param newExtendedContractData - Data to publish.
124
124
  * @returns The hash of the mined tx.
125
125
  */
126
126
  async sendEmitContractDeploymentTx(
127
127
  l2BlockNum: number,
128
128
  l2BlockHash: Buffer,
129
- newContractDataAndBytecode: ContractDataAndBytecode[],
129
+ newExtendedContractData: ExtendedContractData[],
130
130
  ): Promise<(string | undefined)[]> {
131
131
  const hashes: string[] = [];
132
- for (const contractDataAndBytecode of newContractDataAndBytecode) {
132
+ for (const extendedContractData of newExtendedContractData) {
133
133
  const args = [
134
134
  BigInt(l2BlockNum),
135
- contractDataAndBytecode.contractData.contractAddress.toString() as Hex,
136
- contractDataAndBytecode.contractData.portalContractAddress.toString() as Hex,
135
+ extendedContractData.contractData.contractAddress.toString() as Hex,
136
+ extendedContractData.contractData.portalContractAddress.toString() as Hex,
137
137
  `0x${l2BlockHash.toString('hex')}`,
138
- `0x${contractDataAndBytecode.bytecode.toString('hex')}`,
138
+ extendedContractData.partialAddress.toString(true),
139
+ extendedContractData.publicKey.x.toString(true),
140
+ extendedContractData.publicKey.y.toString(true),
141
+ `0x${extendedContractData.bytecode.toString('hex')}`,
139
142
  ] as const;
140
143
 
141
144
  const gas = await this.contractDeploymentEmitterContract.estimateGas.emitContractDeployment(args, {
@@ -16,6 +16,20 @@ export type ProcessedTx = Pick<Tx, 'data' | 'proof' | 'encryptedLogs' | 'unencry
16
16
  isEmpty: boolean;
17
17
  };
18
18
 
19
+ /**
20
+ * Represents a tx that failed to be processed by the sequencer public processor.
21
+ */
22
+ export type FailedTx = {
23
+ /**
24
+ * The failing transaction.
25
+ */
26
+ tx: Tx;
27
+ /**
28
+ * The error that caused the tx to fail.
29
+ */
30
+ error: Error;
31
+ };
32
+
19
33
  /**
20
34
  * Makes a processed tx out of a private only tx that has its proof already set.
21
35
  * @param tx - Source tx that doesn't need further processing.
@@ -26,9 +26,9 @@ import {
26
26
  } from '@aztec/circuits.js/factories';
27
27
  import { padArrayEnd } from '@aztec/foundation/collection';
28
28
  import {
29
- ContractDataAndBytecode,
30
29
  ContractDataSource,
31
30
  EncodedContractFunction,
31
+ ExtendedContractData,
32
32
  FunctionCall,
33
33
  FunctionL2Logs,
34
34
  SiblingPath,
@@ -54,7 +54,7 @@ describe('public_processor', () => {
54
54
  let contractDataSource: MockProxy<ContractDataSource>;
55
55
 
56
56
  let publicFunction: EncodedContractFunction;
57
- let contractData: ContractDataAndBytecode;
57
+ let contractData: ExtendedContractData;
58
58
  let proof: Proof;
59
59
  let root: Buffer;
60
60
 
@@ -66,7 +66,7 @@ describe('public_processor', () => {
66
66
  publicProver = mock<PublicProver>();
67
67
  contractDataSource = mock<ContractDataSource>();
68
68
 
69
- contractData = ContractDataAndBytecode.random();
69
+ contractData = ExtendedContractData.random();
70
70
  publicFunction = EncodedContractFunction.random();
71
71
  proof = makeEmptyProof();
72
72
  root = Buffer.alloc(32, 5);
@@ -74,7 +74,7 @@ describe('public_processor', () => {
74
74
  publicProver.getPublicCircuitProof.mockResolvedValue(proof);
75
75
  publicProver.getPublicKernelCircuitProof.mockResolvedValue(proof);
76
76
  db.getTreeInfo.mockResolvedValue({ root } as TreeInfo);
77
- contractDataSource.getContractDataAndBytecode.mockResolvedValue(contractData);
77
+ contractDataSource.getExtendedContractData.mockResolvedValue(contractData);
78
78
  contractDataSource.getPublicFunction.mockResolvedValue(publicFunction);
79
79
  });
80
80
 
@@ -113,7 +113,7 @@ describe('public_processor', () => {
113
113
  const [processed, failed] = await processor.process([tx]);
114
114
 
115
115
  expect(processed).toEqual([]);
116
- expect(failed).toEqual([tx]);
116
+ expect(failed[0].tx).toEqual(tx);
117
117
  });
118
118
  });
119
119
 
@@ -155,7 +155,9 @@ describe('public_processor', () => {
155
155
  kernelOutput.end.publicCallStack = padArrayEnd(callStackHashes, Fr.ZERO, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX);
156
156
  kernelOutput.end.privateCallStack = padArrayEnd([], Fr.ZERO, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX);
157
157
 
158
- const tx = new Tx(kernelOutput, proof, TxL2Logs.random(2, 3), TxL2Logs.random(3, 2), [], callRequests);
158
+ const tx = new Tx(kernelOutput, proof, TxL2Logs.random(2, 3), TxL2Logs.random(3, 2), callRequests, [
159
+ ExtendedContractData.random(),
160
+ ]);
159
161
 
160
162
  publicExecutor.execute.mockImplementation(execution => {
161
163
  for (const request of callRequests) {
@@ -183,7 +185,14 @@ describe('public_processor', () => {
183
185
  kernelOutput.end.publicCallStack = padArrayEnd([callStackHash], Fr.ZERO, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX);
184
186
  kernelOutput.end.privateCallStack = padArrayEnd([], Fr.ZERO, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX);
185
187
 
186
- const tx = new Tx(kernelOutput, proof, TxL2Logs.random(2, 3), TxL2Logs.random(3, 2), [], [callRequest]);
188
+ const tx = new Tx(
189
+ kernelOutput,
190
+ proof,
191
+ TxL2Logs.random(2, 3),
192
+ TxL2Logs.random(3, 2),
193
+ [callRequest],
194
+ [ExtendedContractData.random()],
195
+ );
187
196
 
188
197
  const publicExecutionResult = makePublicExecutionResultFromRequest(callRequest);
189
198
  publicExecutionResult.nestedExecutions = [
@@ -46,10 +46,9 @@ import { MerkleTreeOperations } from '@aztec/world-state';
46
46
  import { getVerificationKeys } from '../index.js';
47
47
  import { EmptyPublicProver } from '../prover/empty.js';
48
48
  import { PublicProver } from '../prover/index.js';
49
- import { PublicKernelCircuitSimulator } from '../simulator/index.js';
50
- import { getPublicExecutor } from '../simulator/public_executor.js';
49
+ import { PublicKernelCircuitSimulator, getPublicExecutor } from '../simulator/index.js';
51
50
  import { WasmPublicKernelCircuitSimulator } from '../simulator/public_kernel.js';
52
- import { ProcessedTx, makeEmptyProcessedTx, makeProcessedTx } from './processed_tx.js';
51
+ import { FailedTx, ProcessedTx, makeEmptyProcessedTx, makeProcessedTx } from './processed_tx.js';
53
52
  import { getHistoricBlockData } from './utils.js';
54
53
 
55
54
  /**
@@ -107,17 +106,22 @@ export class PublicProcessor {
107
106
  * @param txs - Txs to process.
108
107
  * @returns The list of processed txs with their circuit simulation outputs.
109
108
  */
110
- public async process(txs: Tx[]): Promise<[ProcessedTx[], Tx[]]> {
109
+ public async process(txs: Tx[]): Promise<[ProcessedTx[], FailedTx[]]> {
110
+ // The processor modifies the tx objects in place, so we need to clone them.
111
+ txs = txs.map(tx => Tx.fromJSON(tx.toJSON()));
111
112
  const result: ProcessedTx[] = [];
112
- const failed: Tx[] = [];
113
+ const failed: FailedTx[] = [];
113
114
 
114
115
  for (const tx of txs) {
115
116
  this.log(`Processing tx ${await tx.getTxHash()}`);
116
117
  try {
117
118
  result.push(await this.processTx(tx));
118
119
  } catch (err) {
119
- this.log.error(`Error processing tx ${await tx.getTxHash()}: ${err}`);
120
- failed.push(tx);
120
+ this.log.warn(`Error processing tx ${await tx.getTxHash()}: ${err}`);
121
+ failed.push({
122
+ tx,
123
+ error: err instanceof Error ? err : new Error('Unknown error'),
124
+ });
121
125
  }
122
126
  }
123
127
  return [result, failed];
@@ -170,7 +174,7 @@ export class PublicProcessor {
170
174
  const isExecutionRequest = !isPublicExecutionResult(current);
171
175
  const result = isExecutionRequest ? await this.publicExecutor.execute(current, this.globalVariables) : current;
172
176
  newUnencryptedFunctionLogs.push(result.unencryptedLogs);
173
- const functionSelector = result.execution.functionData.functionSelectorBuffer.toString('hex');
177
+ const functionSelector = result.execution.functionData.selector.toString();
174
178
  this.log(
175
179
  `Running public kernel circuit for ${functionSelector}@${result.execution.contractAddress.toString()}`,
176
180
  );
@@ -3,15 +3,7 @@ import { Fr } from '@aztec/foundation/fields';
3
3
  import { createDebugLogger } from '@aztec/foundation/log';
4
4
  import { RunningPromise } from '@aztec/foundation/running-promise';
5
5
  import { P2P } from '@aztec/p2p';
6
- import {
7
- ContractData,
8
- ContractDataAndBytecode,
9
- L1ToL2MessageSource,
10
- L2Block,
11
- L2BlockSource,
12
- MerkleTreeId,
13
- Tx,
14
- } from '@aztec/types';
6
+ import { L1ToL2MessageSource, L2Block, L2BlockSource, MerkleTreeId, Tx } from '@aztec/types';
15
7
  import { WorldStateStatus, WorldStateSynchroniser } from '@aztec/world-state';
16
8
 
17
9
  import times from 'lodash.times';
@@ -149,8 +141,9 @@ export class Sequencer {
149
141
  const processor = await this.publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables);
150
142
  const [processedTxs, failedTxs] = await processor.process(validTxs);
151
143
  if (failedTxs.length > 0) {
152
- this.log(`Dropping failed txs ${(await Tx.getHashes(failedTxs)).join(', ')}`);
153
- await this.p2pClient.deleteTxs(await Tx.getHashes(failedTxs));
144
+ const failedTxData = failedTxs.map(fail => fail.tx);
145
+ this.log(`Dropping failed txs ${(await Tx.getHashes(failedTxData)).join(', ')}`);
146
+ await this.p2pClient.deleteTxs(await Tx.getHashes(failedTxData));
154
147
  }
155
148
 
156
149
  if (processedTxs.length === 0) {
@@ -170,7 +163,7 @@ export class Sequencer {
170
163
  const block = await this.buildBlock(processedTxs, l1ToL2Messages, emptyTx, newGlobalVariables);
171
164
  this.log(`Assembled block ${block.number}`);
172
165
 
173
- await this.publishContractDataAndBytecode(validTxs, block);
166
+ await this.publishExtendedContractData(validTxs, block);
174
167
 
175
168
  await this.publishL2Block(block);
176
169
  this.log.info(`Submitted rollup block ${block.number} with ${processedTxs.length} transactions`);
@@ -182,28 +175,25 @@ export class Sequencer {
182
175
  }
183
176
 
184
177
  /**
185
- * Gets new contract data and bytecode from the txs and publishes it on chain.
178
+ * Gets new extended contract data from the txs and publishes it on chain.
186
179
  * @param validTxs - The set of real transactions being published as part of the block.
187
180
  * @param block - The L2Block to be published.
188
181
  */
189
- protected async publishContractDataAndBytecode(validTxs: Tx[], block: L2Block) {
182
+ protected async publishExtendedContractData(validTxs: Tx[], block: L2Block) {
190
183
  // Publishes contract data for txs to the network and awaits the tx to be mined
191
184
  this.state = SequencerState.PUBLISHING_CONTRACT_DATA;
192
185
  const newContractData = validTxs
193
186
  .map(tx => {
194
187
  // Currently can only have 1 new contract per tx
195
188
  const newContract = tx.data?.end.newContracts[0];
196
- if (newContract && tx.newContractPublicFunctions?.length) {
197
- return new ContractDataAndBytecode(
198
- new ContractData(newContract.contractAddress, newContract.portalContractAddress),
199
- tx.newContractPublicFunctions,
200
- );
189
+ if (newContract) {
190
+ return tx.newContracts[0];
201
191
  }
202
192
  })
203
193
  .filter((cd): cd is Exclude<typeof cd, undefined> => cd !== undefined);
204
194
 
205
195
  const blockHash = block.getCalldataHash();
206
- this.log(`Publishing contract data and bytecode with block hash ${blockHash.toString('hex')}`);
196
+ this.log(`Publishing extended contract data with block hash ${blockHash.toString('hex')}`);
207
197
 
208
198
  const publishedContractData = await this.publisher.processNewContractData(block.number, blockHash, newContractData);
209
199
  if (publishedContractData) {
@@ -8,6 +8,8 @@ import {
8
8
  RootRollupPublicInputs,
9
9
  } from '@aztec/circuits.js';
10
10
 
11
+ export { getPublicExecutor } from './public_executor.js';
12
+
11
13
  /**
12
14
  * Circuit simulator for the rollup circuits.
13
15
  */
@@ -6,7 +6,7 @@ import {
6
6
  PublicExecutor,
7
7
  PublicStateDB,
8
8
  } from '@aztec/acir-simulator';
9
- import { AztecAddress, CircuitsWasm, EthAddress, Fr, HistoricBlockData } from '@aztec/circuits.js';
9
+ import { AztecAddress, CircuitsWasm, EthAddress, Fr, FunctionSelector, HistoricBlockData } from '@aztec/circuits.js';
10
10
  import { siloCommitment } from '@aztec/circuits.js/abis';
11
11
  import { ContractDataSource, L1ToL2MessageSource, MerkleTreeId } from '@aztec/types';
12
12
  import { MerkleTreeOperations, computePublicDataTreeLeafIndex } from '@aztec/world-state';
@@ -36,11 +36,11 @@ export function getPublicExecutor(
36
36
  */
37
37
  class ContractsDataSourcePublicDB implements PublicContractsDB {
38
38
  constructor(private db: ContractDataSource) {}
39
- async getBytecode(address: AztecAddress, functionSelector: Buffer): Promise<Buffer | undefined> {
40
- return (await this.db.getPublicFunction(address, functionSelector))?.bytecode;
39
+ async getBytecode(address: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
40
+ return (await this.db.getPublicFunction(address, selector))?.bytecode;
41
41
  }
42
- async getIsInternal(address: AztecAddress, functionSelector: Buffer): Promise<boolean | undefined> {
43
- return (await this.db.getPublicFunction(address, functionSelector))?.isInternal;
42
+ async getIsInternal(address: AztecAddress, selector: FunctionSelector): Promise<boolean | undefined> {
43
+ return (await this.db.getPublicFunction(address, selector))?.isInternal;
44
44
  }
45
45
  async getPortalContractAddress(address: AztecAddress): Promise<EthAddress | undefined> {
46
46
  return (await this.db.getContractData(address))?.portalContractAddress;