@aztec/sequencer-client 0.0.1-commit.e6bd8901 → 0.0.1-commit.ee80a48

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.
@@ -60,6 +60,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
60
60
  /** The last slot for which we attempted to perform our voting duties with degraded block production */
61
61
  private lastSlotForFallbackVote: SlotNumber | undefined;
62
62
 
63
+ /** The last slot for which we logged "no committee" warning, to avoid spam */
64
+ private lastSlotForNoCommitteeWarning: SlotNumber | undefined;
65
+
63
66
  /** The last slot for which we triggered a checkpoint proposal job, to prevent duplicate attempts. */
64
67
  private lastSlotForCheckpointProposalJob: SlotNumber | undefined;
65
68
 
@@ -424,8 +427,8 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
424
427
  this.metrics,
425
428
  this,
426
429
  this.setState.bind(this),
427
- this.log,
428
430
  this.tracer,
431
+ this.log.getBindings(),
429
432
  );
430
433
  }
431
434
 
@@ -557,7 +560,10 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
557
560
  proposer = await this.epochCache.getProposerAttesterAddressInSlot(slot);
558
561
  } catch (e) {
559
562
  if (e instanceof NoCommitteeError) {
560
- this.log.warn(`Cannot propose at next L2 slot ${slot} since the committee does not exist on L1`);
563
+ if (this.lastSlotForNoCommitteeWarning !== slot) {
564
+ this.lastSlotForNoCommitteeWarning = slot;
565
+ this.log.warn(`Cannot propose at next L2 slot ${slot} since the committee does not exist on L1`);
566
+ }
561
567
  return [false, undefined];
562
568
  }
563
569
  this.log.error(`Error getting proposer for slot ${slot}`, e);
@@ -1,11 +1,9 @@
1
1
  import { type BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
- import { Timer } from '@aztec/foundation/timer';
4
3
  import { L2Block } from '@aztec/stdlib/block';
5
4
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
6
5
  import { Gas } from '@aztec/stdlib/gas';
7
6
  import type {
8
- BuildBlockInCheckpointResult,
9
7
  FullNodeBlockBuilderConfig,
10
8
  ICheckpointBlockBuilder,
11
9
  ICheckpointsBuilder,
@@ -15,6 +13,7 @@ import type {
15
13
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
16
14
  import { makeAppendOnlyTreeSnapshot } from '@aztec/stdlib/testing';
17
15
  import type { CheckpointGlobalVariables, Tx } from '@aztec/stdlib/tx';
16
+ import type { BuildBlockInCheckpointResult } from '@aztec/validator-client';
18
17
 
19
18
  /**
20
19
  * A fake CheckpointBuilder for testing that implements the same interface as the real one.
@@ -35,6 +34,8 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
35
34
  timestamp: bigint;
36
35
  opts: PublicProcessorLimits;
37
36
  }> = [];
37
+ /** Track all consumed transaction hashes across buildBlock calls */
38
+ public consumedTxHashes: Set<string> = new Set();
38
39
  public completeCheckpointCalled = false;
39
40
  public getCheckpointCalled = false;
40
41
 
@@ -69,8 +70,8 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
69
70
  return this.constants;
70
71
  }
71
72
 
72
- buildBlock(
73
- _pendingTxs: Iterable<Tx> | AsyncIterable<Tx>,
73
+ async buildBlock(
74
+ pendingTxs: Iterable<Tx> | AsyncIterable<Tx>,
74
75
  blockNumber: BlockNumber,
75
76
  timestamp: bigint,
76
77
  opts: PublicProcessorLimits,
@@ -78,7 +79,7 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
78
79
  this.buildBlockCalls.push({ blockNumber, timestamp, opts });
79
80
 
80
81
  if (this.errorOnBuild) {
81
- return Promise.reject(this.errorOnBuild);
82
+ throw this.errorOnBuild;
82
83
  }
83
84
 
84
85
  let block: L2Block;
@@ -97,16 +98,28 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
97
98
  this.builtBlocks.push(block);
98
99
  }
99
100
 
100
- return Promise.resolve({
101
+ // Check that no pending tx has already been consumed
102
+ for await (const tx of pendingTxs) {
103
+ const hash = tx.getTxHash().toString();
104
+ if (this.consumedTxHashes.has(hash)) {
105
+ throw new Error(`Transaction ${hash} was already consumed in a previous block`);
106
+ }
107
+ }
108
+
109
+ // Add used txs to consumed set
110
+ for (const tx of usedTxs) {
111
+ this.consumedTxHashes.add(tx.getTxHash().toString());
112
+ }
113
+
114
+ return {
101
115
  block,
102
116
  publicGas: Gas.empty(),
103
117
  publicProcessorDuration: 0,
104
118
  numTxs: block?.body?.txEffects?.length ?? usedTxs.length,
105
- blockBuildingTimer: new Timer(),
106
119
  usedTxs,
107
120
  failedTxs: [],
108
121
  usedTxBlobFields: block?.body?.txEffects?.reduce((sum, tx) => sum + tx.getNumBlobFields(), 0) ?? 0,
109
- });
122
+ };
110
123
  }
111
124
 
112
125
  completeCheckpoint(): Promise<Checkpoint> {
@@ -170,6 +183,7 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
170
183
  this.usedTxsPerBlock = [];
171
184
  this.blockIndex = 0;
172
185
  this.buildBlockCalls = [];
186
+ this.consumedTxHashes.clear();
173
187
  this.completeCheckpointCalled = false;
174
188
  this.getCheckpointCalled = false;
175
189
  this.errorOnBuild = undefined;