@aztec/sequencer-client 0.76.4-devnet-test-rc3 → 0.77.0-testnet-ignition.17

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 (87) hide show
  1. package/dest/client/index.js +0 -1
  2. package/dest/client/sequencer-client.d.ts +12 -9
  3. package/dest/client/sequencer-client.d.ts.map +1 -1
  4. package/dest/client/sequencer-client.js +55 -60
  5. package/dest/config.d.ts +2 -2
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +41 -46
  8. package/dest/global_variable_builder/global_builder.d.ts +5 -2
  9. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  10. package/dest/global_variable_builder/global_builder.js +45 -31
  11. package/dest/global_variable_builder/index.js +0 -1
  12. package/dest/index.js +0 -1
  13. package/dest/publisher/config.d.ts.map +1 -1
  14. package/dest/publisher/config.js +33 -48
  15. package/dest/publisher/index.js +0 -1
  16. package/dest/publisher/sequencer-publisher-metrics.d.ts +6 -5
  17. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  18. package/dest/publisher/sequencer-publisher-metrics.js +46 -28
  19. package/dest/publisher/sequencer-publisher.d.ts +11 -23
  20. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  21. package/dest/publisher/sequencer-publisher.js +191 -238
  22. package/dest/sequencer/allowed.d.ts +1 -1
  23. package/dest/sequencer/allowed.d.ts.map +1 -1
  24. package/dest/sequencer/allowed.js +6 -13
  25. package/dest/sequencer/config.d.ts +1 -1
  26. package/dest/sequencer/config.d.ts.map +1 -1
  27. package/dest/sequencer/config.js +1 -2
  28. package/dest/sequencer/index.js +0 -1
  29. package/dest/sequencer/metrics.js +26 -18
  30. package/dest/sequencer/sequencer.d.ts +19 -15
  31. package/dest/sequencer/sequencer.d.ts.map +1 -1
  32. package/dest/sequencer/sequencer.js +589 -625
  33. package/dest/sequencer/timetable.d.ts +1 -1
  34. package/dest/sequencer/timetable.d.ts.map +1 -1
  35. package/dest/sequencer/timetable.js +33 -19
  36. package/dest/sequencer/utils.d.ts +2 -1
  37. package/dest/sequencer/utils.d.ts.map +1 -1
  38. package/dest/sequencer/utils.js +22 -32
  39. package/dest/slasher/factory.d.ts +5 -5
  40. package/dest/slasher/factory.d.ts.map +1 -1
  41. package/dest/slasher/factory.js +5 -4
  42. package/dest/slasher/index.js +0 -1
  43. package/dest/slasher/slasher_client.d.ts +4 -4
  44. package/dest/slasher/slasher_client.d.ts.map +1 -1
  45. package/dest/slasher/slasher_client.js +110 -113
  46. package/dest/test/index.d.ts +3 -3
  47. package/dest/test/index.d.ts.map +1 -1
  48. package/dest/test/index.js +4 -1
  49. package/dest/tx_validator/archive_cache.d.ts +3 -3
  50. package/dest/tx_validator/archive_cache.d.ts.map +1 -1
  51. package/dest/tx_validator/archive_cache.js +8 -8
  52. package/dest/tx_validator/gas_validator.d.ts +5 -3
  53. package/dest/tx_validator/gas_validator.d.ts.map +1 -1
  54. package/dest/tx_validator/gas_validator.js +70 -70
  55. package/dest/tx_validator/nullifier_cache.d.ts +2 -2
  56. package/dest/tx_validator/nullifier_cache.d.ts.map +1 -1
  57. package/dest/tx_validator/nullifier_cache.js +9 -9
  58. package/dest/tx_validator/phases_validator.d.ts +3 -2
  59. package/dest/tx_validator/phases_validator.d.ts.map +1 -1
  60. package/dest/tx_validator/phases_validator.js +28 -20
  61. package/dest/tx_validator/test_utils.d.ts +4 -2
  62. package/dest/tx_validator/test_utils.d.ts.map +1 -1
  63. package/dest/tx_validator/test_utils.js +2 -3
  64. package/dest/tx_validator/tx_validator_factory.d.ts +7 -5
  65. package/dest/tx_validator/tx_validator_factory.d.ts.map +1 -1
  66. package/dest/tx_validator/tx_validator_factory.js +14 -13
  67. package/package.json +26 -27
  68. package/src/client/sequencer-client.ts +17 -14
  69. package/src/config.ts +6 -14
  70. package/src/global_variable_builder/global_builder.ts +18 -19
  71. package/src/publisher/config.ts +9 -17
  72. package/src/publisher/sequencer-publisher-metrics.ts +22 -9
  73. package/src/publisher/sequencer-publisher.ts +16 -101
  74. package/src/sequencer/allowed.ts +4 -4
  75. package/src/sequencer/config.ts +1 -1
  76. package/src/sequencer/sequencer.ts +39 -113
  77. package/src/sequencer/timetable.ts +1 -1
  78. package/src/sequencer/utils.ts +2 -1
  79. package/src/slasher/factory.ts +5 -5
  80. package/src/slasher/slasher_client.ts +16 -21
  81. package/src/test/index.ts +3 -3
  82. package/src/tx_validator/archive_cache.ts +4 -3
  83. package/src/tx_validator/gas_validator.ts +22 -31
  84. package/src/tx_validator/nullifier_cache.ts +3 -2
  85. package/src/tx_validator/phases_validator.ts +7 -7
  86. package/src/tx_validator/test_utils.ts +5 -3
  87. package/src/tx_validator/tx_validator_factory.ts +23 -17
@@ -1,47 +1,47 @@
1
+ import type { L2Block } from '@aztec/aztec.js';
2
+ import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
3
+ import { omit } from '@aztec/foundation/collection';
4
+ import { EthAddress } from '@aztec/foundation/eth-address';
5
+ import type { Signature } from '@aztec/foundation/eth-signature';
6
+ import { Fr } from '@aztec/foundation/fields';
7
+ import { createLogger } from '@aztec/foundation/log';
8
+ import { RunningPromise } from '@aztec/foundation/running-promise';
9
+ import { type DateProvider, Timer, elapsed } from '@aztec/foundation/timer';
10
+ import type { P2P } from '@aztec/p2p';
11
+ import type { BlockBuilderFactory } from '@aztec/prover-client/block-builder';
12
+ import type { PublicProcessorFactory } from '@aztec/simulator/server';
13
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
14
+ import type { L2BlockSource } from '@aztec/stdlib/block';
15
+ import type { ContractDataSource } from '@aztec/stdlib/contract';
16
+ import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
17
+ import { Gas } from '@aztec/stdlib/gas';
1
18
  import {
2
- type EpochProofQuote,
3
- type L1RollupConstants,
4
- type L1ToL2MessageSource,
5
- type L2Block,
6
- type L2BlockSource,
19
+ type AllowedElement,
7
20
  SequencerConfigSchema,
8
- Tx,
9
- type TxHash,
10
21
  type WorldStateSynchronizer,
11
- } from '@aztec/circuit-types';
12
- import type { AllowedElement, Signature, WorldStateSynchronizerStatus } from '@aztec/circuit-types/interfaces';
13
- import { type L2BlockBuiltStats } from '@aztec/circuit-types/stats';
22
+ type WorldStateSynchronizerStatus,
23
+ } from '@aztec/stdlib/interfaces/server';
24
+ import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
25
+ import { pickFromSchema } from '@aztec/stdlib/schemas';
26
+ import type { L2BlockBuiltStats } from '@aztec/stdlib/stats';
27
+ import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
14
28
  import {
15
- AppendOnlyTreeSnapshot,
16
29
  BlockHeader,
17
30
  ContentCommitment,
18
- type ContractDataSource,
19
- GENESIS_ARCHIVE_ROOT,
20
- Gas,
21
31
  type GlobalVariables,
22
- INITIAL_L2_BLOCK_NUM,
23
32
  StateReference,
24
- } from '@aztec/circuits.js';
25
- import { AztecAddress } from '@aztec/foundation/aztec-address';
26
- import { omit } from '@aztec/foundation/collection';
27
- import { EthAddress } from '@aztec/foundation/eth-address';
28
- import { Fr } from '@aztec/foundation/fields';
29
- import { createLogger } from '@aztec/foundation/log';
30
- import { RunningPromise } from '@aztec/foundation/running-promise';
31
- import { pickFromSchema } from '@aztec/foundation/schemas';
32
- import { type DateProvider, Timer, elapsed } from '@aztec/foundation/timer';
33
- import { type P2P } from '@aztec/p2p';
34
- import { type BlockBuilderFactory } from '@aztec/prover-client/block-builder';
35
- import { type PublicProcessorFactory } from '@aztec/simulator/server';
33
+ Tx,
34
+ type TxHash,
35
+ } from '@aztec/stdlib/tx';
36
36
  import { Attributes, type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
37
- import { type ValidatorClient } from '@aztec/validator-client';
37
+ import type { ValidatorClient } from '@aztec/validator-client';
38
38
 
39
- import { type GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
39
+ import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
40
40
  import { type SequencerPublisher, VoteType } from '../publisher/sequencer-publisher.js';
41
- import { type SlasherClient } from '../slasher/slasher_client.js';
41
+ import type { SlasherClient } from '../slasher/slasher_client.js';
42
42
  import { createValidatorsForBlockBuilding } from '../tx_validator/tx_validator_factory.js';
43
43
  import { getDefaultAllowedSetupFunctions } from './allowed.js';
44
- import { type SequencerConfig } from './config.js';
44
+ import type { SequencerConfig } from './config.js';
45
45
  import { SequencerMetrics } from './metrics.js';
46
46
  import { SequencerTimetable, SequencerTooSlowError } from './timetable.js';
47
47
  import { SequencerState, orderAttestations } from './utils.js';
@@ -272,9 +272,6 @@ export class Sequencer {
272
272
  VoteType.SLASHING,
273
273
  );
274
274
 
275
- // Start collecting proof quotes for the previous epoch if needed in the background
276
- const createProofQuotePromise = this.createProofClaimForPreviousEpoch(slot);
277
-
278
275
  this.setState(SequencerState.INITIALIZING_PROPOSAL, slot);
279
276
  this.log.verbose(`Preparing proposal for block ${newBlockNumber} at slot ${slot}`, {
280
277
  chainTipArchive,
@@ -315,11 +312,6 @@ export class Sequencer {
315
312
  await enqueueSlashingVotePromise.catch(err => {
316
313
  this.log.error(`Error enqueuing slashing vote`, err, { blockNumber: newBlockNumber, slot });
317
314
  });
318
- await createProofQuotePromise
319
- .then(quote => (quote ? this.publisher.enqueueClaimEpochProofRight(quote) : undefined))
320
- .catch(err => {
321
- this.log.error(`Error creating proof quote`, err, { blockNumber: newBlockNumber, slot });
322
- });
323
315
 
324
316
  await this.publisher.sendRequests();
325
317
 
@@ -460,7 +452,6 @@ export class Sequencer {
460
452
  publicProcessorFork,
461
453
  this.contractDataSource,
462
454
  newGlobalVariables,
463
- !!this.config.enforceFees,
464
455
  this.allowedInSetup,
465
456
  );
466
457
 
@@ -658,54 +649,6 @@ export class Sequencer {
658
649
  return orderAttestations(attestations, committee);
659
650
  }
660
651
 
661
- protected async createProofClaimForPreviousEpoch(slotNumber: bigint): Promise<EpochProofQuote | undefined> {
662
- try {
663
- // Find out which epoch we are currently in
664
- const epochToProve = await this.publisher.getClaimableEpoch();
665
-
666
- if (epochToProve === undefined) {
667
- this.log.trace(`No epoch to claim at slot ${slotNumber}`);
668
- return undefined;
669
- }
670
-
671
- // Get quotes for the epoch to be proven
672
- this.log.debug(`Collecting proof quotes for epoch ${epochToProve}`);
673
- const p2pQuotes = await this.p2pClient
674
- .getEpochProofQuotes(epochToProve)
675
- .then(quotes =>
676
- quotes
677
- .filter(x => x.payload.validUntilSlot >= slotNumber)
678
- .filter(x => x.payload.epochToProve === epochToProve),
679
- );
680
- this.log.verbose(`Retrieved ${p2pQuotes.length} quotes for slot ${slotNumber} epoch ${epochToProve}`, {
681
- epochToProve,
682
- slotNumber,
683
- quotes: p2pQuotes.map(q => q.payload),
684
- });
685
- if (!p2pQuotes.length) {
686
- return undefined;
687
- }
688
-
689
- // ensure these quotes are still valid for the slot and have the contract validate them
690
- const validQuotes = await this.publisher.filterValidQuotes(p2pQuotes);
691
-
692
- if (!validQuotes.length) {
693
- this.log.warn(`Failed to find any valid proof quotes`);
694
- return undefined;
695
- }
696
- // pick the quote with the lowest fee
697
- const sortedQuotes = validQuotes.sort(
698
- (a: EpochProofQuote, b: EpochProofQuote) => a.payload.basisPointFee - b.payload.basisPointFee,
699
- );
700
- const quote = sortedQuotes[0];
701
- this.log.info(`Selected proof quote for proof claim`, { quote: quote.toInspect() });
702
- return quote;
703
- } catch (err) {
704
- this.log.error(`Failed to create proof claim for previous epoch`, err, { slotNumber });
705
- return undefined;
706
- }
707
- }
708
-
709
652
  /**
710
653
  * Publishes the L2Block to the rollup contract.
711
654
  * @param block - The L2Block to be published.
@@ -734,29 +677,6 @@ export class Sequencer {
734
677
  }
735
678
  }
736
679
 
737
- @trackSpan(
738
- 'Sequencer.claimEpochProofRightIfAvailable',
739
- slotNumber => ({ [Attributes.SLOT_NUMBER]: Number(slotNumber) }),
740
- epoch => ({ [Attributes.EPOCH_NUMBER]: Number(epoch) }),
741
- )
742
- /** Collects an epoch proof quote if there is an epoch to prove, and submits it to the L1 contract. */
743
- protected async claimEpochProofRightIfAvailable(slotNumber: bigint) {
744
- const proofQuote = await this.createProofClaimForPreviousEpoch(slotNumber);
745
- if (proofQuote === undefined) {
746
- return;
747
- }
748
-
749
- const epoch = proofQuote.payload.epochToProve;
750
- const ctx = { slotNumber, epoch, quote: proofQuote.toInspect() };
751
- this.log.verbose(`Claiming proof right for epoch ${epoch}`, ctx);
752
- const enqueued = this.publisher.enqueueClaimEpochProofRight(proofQuote);
753
- if (!enqueued) {
754
- throw new Error(`Failed to enqueue claim of proof right for epoch ${epoch}`);
755
- }
756
- this.log.info(`Enqueued claim of proof right for epoch ${epoch}`, ctx);
757
- return epoch;
758
- }
759
-
760
680
  /**
761
681
  * Returns whether all dependencies have caught up.
762
682
  * We don't check against the previous block submitted since it may have been reorg'd out.
@@ -764,7 +684,12 @@ export class Sequencer {
764
684
  */
765
685
  protected async getChainTip(): Promise<{ blockNumber: number; archive: Fr } | undefined> {
766
686
  const syncedBlocks = await Promise.all([
767
- this.worldState.status().then((s: WorldStateSynchronizerStatus) => s.syncedToL2Block),
687
+ this.worldState.status().then((s: WorldStateSynchronizerStatus) => {
688
+ return {
689
+ number: s.syncSummary.latestBlockNumber,
690
+ hash: s.syncSummary.latestBlockHash,
691
+ };
692
+ }),
768
693
  this.l2BlockSource.getL2Tips().then(t => t.latest),
769
694
  this.p2pClient.getStatus().then(p2p => p2p.syncedToL2Block),
770
695
  this.l1ToL2MessageSource.getBlockNumber(),
@@ -806,7 +731,8 @@ export class Sequencer {
806
731
 
807
732
  return { blockNumber: block.number, archive: block.archive.root };
808
733
  } else {
809
- return { blockNumber: INITIAL_L2_BLOCK_NUM - 1, archive: new Fr(GENESIS_ARCHIVE_ROOT) };
734
+ const archive = new Fr((await this.worldState.getCommitted().getTreeInfo(MerkleTreeId.ARCHIVE)).root);
735
+ return { blockNumber: INITIAL_L2_BLOCK_NUM - 1, archive };
810
736
  }
811
737
  }
812
738
 
@@ -1,6 +1,6 @@
1
1
  import { createLogger } from '@aztec/aztec.js';
2
2
 
3
- import { type SequencerMetrics } from './metrics.js';
3
+ import type { SequencerMetrics } from './metrics.js';
4
4
  import { SequencerState } from './utils.js';
5
5
 
6
6
  export class SequencerTimetable {
@@ -1,5 +1,6 @@
1
- import type { BlockAttestation, EthAddress } from '@aztec/circuit-types';
1
+ import type { EthAddress } from '@aztec/foundation/eth-address';
2
2
  import { Signature } from '@aztec/foundation/eth-signature';
3
+ import type { BlockAttestation } from '@aztec/stdlib/p2p';
3
4
 
4
5
  export enum SequencerState {
5
6
  /**
@@ -1,13 +1,13 @@
1
- import type { L2BlockSource } from '@aztec/circuit-types';
2
- import { type L1ContractsConfig, type L1ReaderConfig } from '@aztec/ethereum';
1
+ import type { L1ContractsConfig, L1ReaderConfig } from '@aztec/ethereum';
3
2
  import { createLogger } from '@aztec/foundation/log';
4
- import { type AztecAsyncKVStore } from '@aztec/kv-store';
5
- import { type DataStoreConfig } from '@aztec/kv-store/config';
3
+ import type { AztecAsyncKVStore } from '@aztec/kv-store';
4
+ import type { DataStoreConfig } from '@aztec/kv-store/config';
6
5
  import { createStore } from '@aztec/kv-store/lmdb-v2';
6
+ import type { L2BlockSource } from '@aztec/stdlib/block';
7
7
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
8
8
 
9
9
  import { SlasherClient } from './slasher_client.js';
10
- import { type SlasherConfig } from './slasher_client.js';
10
+ import type { SlasherConfig } from './slasher_client.js';
11
11
 
12
12
  export const createSlasherClient = async (
13
13
  _config: SlasherConfig & DataStoreConfig & L1ContractsConfig & L1ReaderConfig,
@@ -1,3 +1,14 @@
1
+ import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
2
+ import {
3
+ type L1ContractsConfig,
4
+ type L1ReaderConfig,
5
+ type ViemPublicClient,
6
+ createEthereumChain,
7
+ } from '@aztec/ethereum';
8
+ import { EthAddress } from '@aztec/foundation/eth-address';
9
+ import { createLogger } from '@aztec/foundation/log';
10
+ import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncSingleton } from '@aztec/kv-store';
11
+ import { SlashFactoryAbi } from '@aztec/l1-artifacts';
1
12
  import {
2
13
  type L2Block,
3
14
  type L2BlockId,
@@ -5,25 +16,10 @@ import {
5
16
  L2BlockStream,
6
17
  type L2BlockStreamEvent,
7
18
  type L2Tips,
8
- } from '@aztec/circuit-types';
9
- import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
10
- import { type L1ContractsConfig, type L1ReaderConfig, createEthereumChain } from '@aztec/ethereum';
11
- import { EthAddress } from '@aztec/foundation/eth-address';
12
- import { createLogger } from '@aztec/foundation/log';
13
- import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncSingleton } from '@aztec/kv-store';
14
- import { SlashFactoryAbi } from '@aztec/l1-artifacts';
19
+ } from '@aztec/stdlib/block';
15
20
  import { type TelemetryClient, WithTracer, getTelemetryClient } from '@aztec/telemetry-client';
16
21
 
17
- import {
18
- type Chain,
19
- type GetContractReturnType,
20
- type HttpTransport,
21
- type PublicClient,
22
- createPublicClient,
23
- getAddress,
24
- getContract,
25
- http,
26
- } from 'viem';
22
+ import { type GetContractReturnType, createPublicClient, fallback, getAddress, getContract, http } from 'viem';
27
23
 
28
24
  /**
29
25
  * Enum defining the possible states of the Slasher client.
@@ -100,8 +96,7 @@ export class SlasherClient extends WithTracer {
100
96
 
101
97
  private slashEvents: SlashEvent[] = [];
102
98
 
103
- protected slashFactoryContract?: GetContractReturnType<typeof SlashFactoryAbi, PublicClient<HttpTransport, Chain>> =
104
- undefined;
99
+ protected slashFactoryContract?: GetContractReturnType<typeof SlashFactoryAbi, ViemPublicClient> = undefined;
105
100
 
106
101
  // The amount to slash for a prune.
107
102
  // Note that we set it to 0, such that no actual slashing will happen, but the event will be fired,
@@ -127,10 +122,10 @@ export class SlasherClient extends WithTracer {
127
122
  this.synchedProvenBlockNumber = store.openSingleton('slasher_last_proven_l2_block');
128
123
 
129
124
  if (config.l1Contracts.slashFactoryAddress && config.l1Contracts.slashFactoryAddress !== EthAddress.ZERO) {
130
- const chain = createEthereumChain(config.l1RpcUrl, config.l1ChainId);
125
+ const chain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
131
126
  const publicClient = createPublicClient({
132
127
  chain: chain.chainInfo,
133
- transport: http(chain.rpcUrl),
128
+ transport: fallback(chain.rpcUrls.map(url => http(url))),
134
129
  pollingInterval: config.viemPollingIntervalMS,
135
130
  });
136
131
 
package/src/test/index.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { type PublicProcessorFactory } from '@aztec/simulator/server';
1
+ import type { PublicProcessorFactory } from '@aztec/simulator/server';
2
2
 
3
3
  import { SequencerClient } from '../client/sequencer-client.js';
4
- import { type SequencerPublisher } from '../publisher/sequencer-publisher.js';
4
+ import type { SequencerPublisher } from '../publisher/sequencer-publisher.js';
5
5
  import { Sequencer } from '../sequencer/sequencer.js';
6
- import { type SequencerTimetable } from '../sequencer/timetable.js';
6
+ import type { SequencerTimetable } from '../sequencer/timetable.js';
7
7
 
8
8
  class TestSequencer_ extends Sequencer {
9
9
  public override publicProcessorFactory!: PublicProcessorFactory;
@@ -1,6 +1,7 @@
1
- import { MerkleTreeId, type MerkleTreeReadOperations } from '@aztec/circuit-types';
2
- import { type Fr } from '@aztec/circuits.js';
3
- import { type ArchiveSource } from '@aztec/p2p';
1
+ import type { Fr } from '@aztec/foundation/fields';
2
+ import type { ArchiveSource } from '@aztec/p2p';
3
+ import type { MerkleTreeReadOperations } from '@aztec/stdlib/interfaces/server';
4
+ import { MerkleTreeId } from '@aztec/stdlib/trees';
4
5
 
5
6
  /**
6
7
  * Implements an archive source by checking a DB and an in-memory collection.
@@ -1,8 +1,11 @@
1
- import { type Tx, TxExecutionPhase, type TxValidationResult, type TxValidator } from '@aztec/circuit-types';
2
- import { type AztecAddress, Fr, FunctionSelector, type GasFees } from '@aztec/circuits.js';
3
- import { U128 } from '@aztec/foundation/abi';
1
+ import { Fr } from '@aztec/foundation/fields';
4
2
  import { createLogger } from '@aztec/foundation/log';
5
- import { computeFeePayerBalanceStorageSlot, getExecutionRequestsByPhase } from '@aztec/simulator/server';
3
+ import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
4
+ import { getExecutionRequestsByPhase } from '@aztec/simulator/server';
5
+ import { FunctionSelector } from '@aztec/stdlib/abi';
6
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
7
+ import type { GasFees } from '@aztec/stdlib/gas';
8
+ import { type Tx, TxExecutionPhase, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
6
9
 
7
10
  /** Provides a view into public contract state */
8
11
  export interface PublicStateSource {
@@ -13,23 +16,16 @@ export class GasTxValidator implements TxValidator<Tx> {
13
16
  #log = createLogger('sequencer:tx_validator:tx_gas');
14
17
  #publicDataSource: PublicStateSource;
15
18
  #feeJuiceAddress: AztecAddress;
16
- #enforceFees: boolean;
17
19
  #gasFees: GasFees;
18
20
 
19
- constructor(
20
- publicDataSource: PublicStateSource,
21
- feeJuiceAddress: AztecAddress,
22
- enforceFees: boolean,
23
- gasFees: GasFees,
24
- ) {
21
+ constructor(publicDataSource: PublicStateSource, feeJuiceAddress: AztecAddress, gasFees: GasFees) {
25
22
  this.#publicDataSource = publicDataSource;
26
23
  this.#feeJuiceAddress = feeJuiceAddress;
27
- this.#enforceFees = enforceFees;
28
24
  this.#gasFees = gasFees;
29
25
  }
30
26
 
31
- validateTx(tx: Tx): Promise<TxValidationResult> {
32
- if (this.#shouldSkip(tx)) {
27
+ async validateTx(tx: Tx): Promise<TxValidationResult> {
28
+ if (await this.#shouldSkip(tx)) {
33
29
  return Promise.resolve({ result: 'skipped', reason: ['Insufficient fee per gas'] });
34
30
  }
35
31
  return this.#validateTxFee(tx);
@@ -37,11 +33,11 @@ export class GasTxValidator implements TxValidator<Tx> {
37
33
 
38
34
  /**
39
35
  * Check whether the tx's max fees are valid for the current block, and skip if not.
40
- * We skip instead of invalidating since the tx may become elligible later.
36
+ * We skip instead of invalidating since the tx may become eligible later.
41
37
  * Note that circuits check max fees even if fee payer is unset, so we
42
38
  * keep this validation even if the tx does not pay fees.
43
39
  */
44
- #shouldSkip(tx: Tx): boolean {
40
+ async #shouldSkip(tx: Tx): Promise<boolean> {
45
41
  const gasSettings = tx.data.constants.txContext.gasSettings;
46
42
 
47
43
  // Skip the tx if its max fees are not enough for the current block's gas fees.
@@ -51,22 +47,16 @@ export class GasTxValidator implements TxValidator<Tx> {
51
47
  maxFeesPerGas.feePerL2Gas.lt(this.#gasFees.feePerL2Gas);
52
48
 
53
49
  if (notEnoughMaxFees) {
54
- this.#log.warn(`Skipping transaction ${tx.getTxHash()} due to insufficient fee per gas`);
50
+ this.#log.warn(`Skipping transaction ${await tx.getTxHash()} due to insufficient fee per gas`, {
51
+ txMaxFeesPerGas: maxFeesPerGas.toInspect(),
52
+ currentGasFees: this.#gasFees.toInspect(),
53
+ });
55
54
  }
56
55
  return notEnoughMaxFees;
57
56
  }
58
57
 
59
58
  async #validateTxFee(tx: Tx): Promise<TxValidationResult> {
60
59
  const feePayer = tx.data.feePayer;
61
- // TODO(@spalladino) Eventually remove the is_zero condition as we should always charge fees to every tx
62
- if (feePayer.isZero()) {
63
- if (this.#enforceFees) {
64
- this.#log.warn(`Rejecting transaction ${tx.getTxHash()} due to missing fee payer`);
65
- return { result: 'invalid', reason: ['Missing fee payer'] };
66
- } else {
67
- return { result: 'valid' };
68
- }
69
- }
70
60
 
71
61
  // Compute the maximum fee that this tx may pay, based on its gasLimits and maxFeePerGas
72
62
  const feeLimit = tx.data.constants.txContext.gasSettings.getFeeLimit();
@@ -80,7 +70,7 @@ export class GasTxValidator implements TxValidator<Tx> {
80
70
  // If there is a claim in this tx that increases the fee payer balance in Fee Juice, add it to balance
81
71
  const setupFns = getExecutionRequestsByPhase(tx, TxExecutionPhase.SETUP);
82
72
  const increasePublicBalanceSelector = await FunctionSelector.fromSignature(
83
- '_increase_public_balance((Field),(Field,Field))',
73
+ '_increase_public_balance((Field),u128)',
84
74
  );
85
75
  const claimFunctionCall = setupFns.find(
86
76
  fn =>
@@ -93,10 +83,11 @@ export class GasTxValidator implements TxValidator<Tx> {
93
83
  !fn.callContext.isStaticCall,
94
84
  );
95
85
 
96
- // `amount` in the claim function call arguments occupies 2 fields as it is represented as U128.
97
- const balance = claimFunctionCall
98
- ? initialBalance.add(new Fr(U128.fromFields(claimFunctionCall.args.slice(2, 4)).toInteger()))
99
- : initialBalance;
86
+ // The claim amount is at index 2 in the args array because:
87
+ // - Index 0: Target function selector (due to dispatch routing)
88
+ // - Index 1: Amount recipient
89
+ // - Index 2: Amount being claimed
90
+ const balance = claimFunctionCall ? initialBalance.add(claimFunctionCall.args[2]) : initialBalance;
100
91
  if (balance.lt(feeLimit)) {
101
92
  this.#log.warn(`Rejecting transaction due to not enough fee payer balance`, {
102
93
  feePayer,
@@ -1,5 +1,6 @@
1
- import { MerkleTreeId, type MerkleTreeReadOperations } from '@aztec/circuit-types';
2
- import { type NullifierSource } from '@aztec/p2p';
1
+ import type { NullifierSource } from '@aztec/p2p';
2
+ import type { MerkleTreeReadOperations } from '@aztec/stdlib/interfaces/server';
3
+ import { MerkleTreeId } from '@aztec/stdlib/trees';
3
4
 
4
5
  /**
5
6
  * Implements a nullifier source by checking a DB and an in-memory collection.
@@ -1,14 +1,14 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import { ContractsDataSourcePublicDB, getExecutionRequestsByPhase } from '@aztec/simulator/server';
3
+ import type { ContractDataSource } from '@aztec/stdlib/contract';
4
+ import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
1
5
  import {
2
- type AllowedElement,
3
6
  type PublicExecutionRequest,
4
7
  Tx,
5
8
  TxExecutionPhase,
6
9
  type TxValidationResult,
7
10
  type TxValidator,
8
- } from '@aztec/circuit-types';
9
- import { type ContractDataSource } from '@aztec/circuits.js';
10
- import { createLogger } from '@aztec/foundation/log';
11
- import { ContractsDataSourcePublicDB, getExecutionRequestsByPhase } from '@aztec/simulator/server';
11
+ } from '@aztec/stdlib/tx';
12
12
 
13
13
  export class PhasesTxValidator implements TxValidator<Tx> {
14
14
  #log = createLogger('sequencer:tx_validator:tx_phases');
@@ -78,14 +78,14 @@ export class PhasesTxValidator implements TxValidator<Tx> {
78
78
  }
79
79
 
80
80
  if ('classId' in entry && !('selector' in entry)) {
81
- if (contractClass.contractClassId.equals(entry.classId)) {
81
+ if (contractClass.currentContractClassId.equals(entry.classId)) {
82
82
  return true;
83
83
  }
84
84
  }
85
85
 
86
86
  if ('classId' in entry && 'selector' in entry) {
87
87
  if (
88
- contractClass.contractClassId.equals(entry.classId) &&
88
+ contractClass.currentContractClassId.equals(entry.classId) &&
89
89
  (entry.selector === undefined || entry.selector.equals(functionSelector))
90
90
  ) {
91
91
  return true;
@@ -1,6 +1,8 @@
1
- import { type Tx } from '@aztec/circuit-types';
2
- import { type AztecAddress, type Fr, type FunctionSelector } from '@aztec/circuits.js';
3
- import { computeVarArgsHash } from '@aztec/circuits.js/hash';
1
+ import type { Fr } from '@aztec/foundation/fields';
2
+ import type { FunctionSelector } from '@aztec/stdlib/abi';
3
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
+ import { computeVarArgsHash } from '@aztec/stdlib/hash';
5
+ import type { Tx } from '@aztec/stdlib/tx';
4
6
 
5
7
  export function patchNonRevertibleFn(
6
8
  tx: Tx,
@@ -1,12 +1,4 @@
1
- import {
2
- type AllowedElement,
3
- type ClientProtocolCircuitVerifier,
4
- type MerkleTreeReadOperations,
5
- type ProcessedTx,
6
- type Tx,
7
- type TxValidator,
8
- } from '@aztec/circuit-types';
9
- import { type AztecAddress, type ContractDataSource, Fr, type GasFees, type GlobalVariables } from '@aztec/circuits.js';
1
+ import { Fr } from '@aztec/foundation/fields';
10
2
  import {
11
3
  AggregateTxValidator,
12
4
  BlockHeaderTxValidator,
@@ -17,6 +9,15 @@ import {
17
9
  } from '@aztec/p2p';
18
10
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
19
11
  import { readPublicState } from '@aztec/simulator/server';
12
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
13
+ import type { ContractDataSource } from '@aztec/stdlib/contract';
14
+ import type { GasFees } from '@aztec/stdlib/gas';
15
+ import type {
16
+ AllowedElement,
17
+ ClientProtocolCircuitVerifier,
18
+ MerkleTreeReadOperations,
19
+ } from '@aztec/stdlib/interfaces/server';
20
+ import { GlobalVariables, type ProcessedTx, type Tx, type TxValidator } from '@aztec/stdlib/tx';
20
21
 
21
22
  import { ArchiveCache } from './archive_cache.js';
22
23
  import { GasTxValidator, type PublicStateSource } from './gas_validator.js';
@@ -27,24 +28,32 @@ export function createValidatorForAcceptingTxs(
27
28
  db: MerkleTreeReadOperations,
28
29
  contractDataSource: ContractDataSource,
29
30
  verifier: ClientProtocolCircuitVerifier | undefined,
30
- data: {
31
+ {
32
+ blockNumber,
33
+ l1ChainId,
34
+ setupAllowList,
35
+ gasFees,
36
+ skipFeeEnforcement,
37
+ }: {
31
38
  blockNumber: number;
32
39
  l1ChainId: number;
33
- enforceFees: boolean;
34
40
  setupAllowList: AllowedElement[];
35
41
  gasFees: GasFees;
42
+ skipFeeEnforcement?: boolean;
36
43
  },
37
44
  ): TxValidator<Tx> {
38
- const { blockNumber, l1ChainId, enforceFees, setupAllowList, gasFees } = data;
39
45
  const validators: TxValidator<Tx>[] = [
40
46
  new DataTxValidator(),
41
47
  new MetadataTxValidator(new Fr(l1ChainId), new Fr(blockNumber)),
42
48
  new DoubleSpendTxValidator(new NullifierCache(db)),
43
49
  new PhasesTxValidator(contractDataSource, setupAllowList),
44
- new GasTxValidator(new DatabasePublicStateSource(db), ProtocolContractAddress.FeeJuice, enforceFees, gasFees),
45
50
  new BlockHeaderTxValidator(new ArchiveCache(db)),
46
51
  ];
47
52
 
53
+ if (!skipFeeEnforcement) {
54
+ validators.push(new GasTxValidator(new DatabasePublicStateSource(db), ProtocolContractAddress.FeeJuice, gasFees));
55
+ }
56
+
48
57
  if (verifier) {
49
58
  validators.push(new TxProofValidator(verifier));
50
59
  }
@@ -56,7 +65,6 @@ export function createValidatorsForBlockBuilding(
56
65
  db: MerkleTreeReadOperations,
57
66
  contractDataSource: ContractDataSource,
58
67
  globalVariables: GlobalVariables,
59
- enforceFees: boolean,
60
68
  setupAllowList: AllowedElement[],
61
69
  ): {
62
70
  preprocessValidator: TxValidator<Tx>;
@@ -73,7 +81,6 @@ export function createValidatorsForBlockBuilding(
73
81
  archiveCache,
74
82
  publicStateSource,
75
83
  contractDataSource,
76
- enforceFees,
77
84
  globalVariables,
78
85
  setupAllowList,
79
86
  ),
@@ -95,7 +102,6 @@ function preprocessValidator(
95
102
  archiveCache: ArchiveCache,
96
103
  publicStateSource: PublicStateSource,
97
104
  contractDataSource: ContractDataSource,
98
- enforceFees: boolean,
99
105
  globalVariables: GlobalVariables,
100
106
  setupAllowList: AllowedElement[],
101
107
  ): TxValidator<Tx> {
@@ -104,7 +110,7 @@ function preprocessValidator(
104
110
  new MetadataTxValidator(globalVariables.chainId, globalVariables.blockNumber),
105
111
  new DoubleSpendTxValidator(nullifierCache),
106
112
  new PhasesTxValidator(contractDataSource, setupAllowList),
107
- new GasTxValidator(publicStateSource, ProtocolContractAddress.FeeJuice, enforceFees, globalVariables.gasFees),
113
+ new GasTxValidator(publicStateSource, ProtocolContractAddress.FeeJuice, globalVariables.gasFees),
108
114
  new BlockHeaderTxValidator(archiveCache),
109
115
  );
110
116
  }