@aztec/sequencer-client 3.0.0-canary.a9708bd → 3.0.0-devnet.20251212

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 (73) hide show
  1. package/dest/client/index.d.ts +1 -1
  2. package/dest/client/sequencer-client.d.ts +7 -6
  3. package/dest/client/sequencer-client.d.ts.map +1 -1
  4. package/dest/client/sequencer-client.js +23 -14
  5. package/dest/config.d.ts +5 -3
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +21 -1
  8. package/dest/global_variable_builder/global_builder.d.ts +5 -7
  9. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  10. package/dest/global_variable_builder/global_builder.js +12 -8
  11. package/dest/global_variable_builder/index.d.ts +1 -1
  12. package/dest/index.d.ts +1 -1
  13. package/dest/publisher/config.d.ts +9 -10
  14. package/dest/publisher/config.d.ts.map +1 -1
  15. package/dest/publisher/config.js +19 -17
  16. package/dest/publisher/index.d.ts +2 -2
  17. package/dest/publisher/index.d.ts.map +1 -1
  18. package/dest/publisher/index.js +1 -1
  19. package/dest/publisher/sequencer-publisher-factory.d.ts +9 -3
  20. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  21. package/dest/publisher/sequencer-publisher-factory.js +8 -1
  22. package/dest/publisher/sequencer-publisher-metrics.d.ts +2 -2
  23. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  24. package/dest/publisher/sequencer-publisher-metrics.js +1 -1
  25. package/dest/publisher/sequencer-publisher.d.ts +53 -50
  26. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  27. package/dest/publisher/sequencer-publisher.js +187 -132
  28. package/dest/sequencer/block_builder.d.ts +6 -8
  29. package/dest/sequencer/block_builder.d.ts.map +1 -1
  30. package/dest/sequencer/block_builder.js +18 -9
  31. package/dest/sequencer/config.d.ts +2 -2
  32. package/dest/sequencer/config.d.ts.map +1 -1
  33. package/dest/sequencer/errors.d.ts +11 -0
  34. package/dest/sequencer/errors.d.ts.map +1 -0
  35. package/dest/sequencer/errors.js +15 -0
  36. package/dest/sequencer/index.d.ts +1 -1
  37. package/dest/sequencer/metrics.d.ts +17 -20
  38. package/dest/sequencer/metrics.d.ts.map +1 -1
  39. package/dest/sequencer/metrics.js +59 -87
  40. package/dest/sequencer/sequencer.d.ts +54 -32
  41. package/dest/sequencer/sequencer.d.ts.map +1 -1
  42. package/dest/sequencer/sequencer.js +458 -184
  43. package/dest/sequencer/timetable.d.ts +4 -8
  44. package/dest/sequencer/timetable.d.ts.map +1 -1
  45. package/dest/sequencer/timetable.js +3 -10
  46. package/dest/sequencer/utils.d.ts +11 -25
  47. package/dest/sequencer/utils.d.ts.map +1 -1
  48. package/dest/sequencer/utils.js +9 -24
  49. package/dest/test/index.d.ts +2 -2
  50. package/dest/test/index.d.ts.map +1 -1
  51. package/dest/tx_validator/nullifier_cache.d.ts +1 -1
  52. package/dest/tx_validator/nullifier_cache.d.ts.map +1 -1
  53. package/dest/tx_validator/tx_validator_factory.d.ts +4 -3
  54. package/dest/tx_validator/tx_validator_factory.d.ts.map +1 -1
  55. package/dest/tx_validator/tx_validator_factory.js +12 -9
  56. package/package.json +32 -31
  57. package/src/client/sequencer-client.ts +24 -18
  58. package/src/config.ts +23 -6
  59. package/src/global_variable_builder/global_builder.ts +19 -17
  60. package/src/publisher/config.ts +29 -27
  61. package/src/publisher/index.ts +1 -1
  62. package/src/publisher/sequencer-publisher-factory.ts +16 -3
  63. package/src/publisher/sequencer-publisher-metrics.ts +1 -1
  64. package/src/publisher/sequencer-publisher.ts +257 -183
  65. package/src/sequencer/block_builder.ts +23 -28
  66. package/src/sequencer/config.ts +1 -1
  67. package/src/sequencer/errors.ts +21 -0
  68. package/src/sequencer/metrics.ts +71 -98
  69. package/src/sequencer/sequencer.ts +546 -237
  70. package/src/sequencer/timetable.ts +10 -14
  71. package/src/sequencer/utils.ts +10 -24
  72. package/src/test/index.ts +1 -1
  73. package/src/tx_validator/tx_validator_factory.ts +13 -7
@@ -1,24 +1,25 @@
1
- import { MerkleTreeId, elapsed } from '@aztec/aztec.js';
2
- import { pick } from '@aztec/foundation/collection';
3
- import type { Fr } from '@aztec/foundation/fields';
1
+ import { MerkleTreeId } from '@aztec/aztec.js/trees';
2
+ import { BlockNumber } from '@aztec/foundation/branded-types';
3
+ import { merge, pick } from '@aztec/foundation/collection';
4
+ import type { Fr } from '@aztec/foundation/curves/bn254';
4
5
  import { createLogger } from '@aztec/foundation/log';
5
6
  import { retryUntil } from '@aztec/foundation/retry';
6
7
  import { bufferToHex } from '@aztec/foundation/string';
7
- import { DateProvider, Timer } from '@aztec/foundation/timer';
8
+ import { DateProvider, Timer, elapsed } from '@aztec/foundation/timer';
8
9
  import { getDefaultAllowedSetupFunctions } from '@aztec/p2p/msg_validators';
9
10
  import { LightweightBlockFactory } from '@aztec/prover-client/block-factory';
10
11
  import {
11
12
  GuardedMerkleTreeOperations,
12
13
  PublicContractsDB,
13
14
  PublicProcessor,
14
- TelemetryPublicTxSimulator,
15
+ createPublicTxSimulatorForBlockBuilding,
15
16
  } from '@aztec/simulator/server';
16
- import type { ChainConfig, SequencerConfig } from '@aztec/stdlib/config';
17
17
  import type { ContractDataSource } from '@aztec/stdlib/contract';
18
18
  import { type L1RollupConstants, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
19
19
  import { Gas } from '@aztec/stdlib/gas';
20
20
  import type {
21
21
  BuildBlockResult,
22
+ FullNodeBlockBuilderConfig,
22
23
  IFullNodeBlockBuilder,
23
24
  MerkleTreeWriteOperations,
24
25
  PublicProcessorLimits,
@@ -46,7 +47,7 @@ export async function buildBlock(
46
47
  ): Promise<BuildBlockResult> {
47
48
  const blockBuildingTimer = new Timer();
48
49
  const blockNumber = newGlobalVariables.blockNumber;
49
- const slot = newGlobalVariables.slotNumber.toBigInt();
50
+ const slot = newGlobalVariables.slotNumber;
50
51
  const msgCount = l1ToL2Messages.length;
51
52
  const stateReference = await worldStateFork.getStateReference();
52
53
  const archiveTree = await worldStateFork.getTreeInfo(MerkleTreeId.ARCHIVE);
@@ -89,9 +90,14 @@ export async function buildBlock(
89
90
  return res;
90
91
  }
91
92
 
92
- type FullNodeBlockBuilderConfig = Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'> &
93
- Pick<ChainConfig, 'l1ChainId' | 'rollupVersion'> &
94
- Pick<SequencerConfig, 'txPublicSetupAllowList' | 'fakeProcessingDelayPerTxMs'>;
93
+ const FullNodeBlockBuilderConfigKeys = [
94
+ 'l1GenesisTime',
95
+ 'slotDuration',
96
+ 'l1ChainId',
97
+ 'rollupVersion',
98
+ 'txPublicSetupAllowList',
99
+ 'fakeProcessingDelayPerTxMs',
100
+ ] as const;
95
101
 
96
102
  export class FullNodeBlockBuilder implements IFullNodeBlockBuilder {
97
103
  constructor(
@@ -103,19 +109,11 @@ export class FullNodeBlockBuilder implements IFullNodeBlockBuilder {
103
109
  ) {}
104
110
 
105
111
  public getConfig(): FullNodeBlockBuilderConfig {
106
- return pick(
107
- this.config,
108
- 'l1GenesisTime',
109
- 'slotDuration',
110
- 'l1ChainId',
111
- 'rollupVersion',
112
- 'txPublicSetupAllowList',
113
- 'fakeProcessingDelayPerTxMs',
114
- );
112
+ return pick(this.config, ...FullNodeBlockBuilderConfigKeys);
115
113
  }
116
114
 
117
- public updateConfig(config: FullNodeBlockBuilderConfig) {
118
- this.config = config;
115
+ public updateConfig(config: Partial<FullNodeBlockBuilderConfig>) {
116
+ this.config = merge(this.config, pick(config, ...FullNodeBlockBuilderConfigKeys));
119
117
  }
120
118
 
121
119
  public async makeBlockBuilderDeps(globalVariables: GlobalVariables, fork: MerkleTreeWriteOperations) {
@@ -123,13 +121,10 @@ export class FullNodeBlockBuilder implements IFullNodeBlockBuilder {
123
121
  const contractsDB = new PublicContractsDB(this.contractDataSource);
124
122
  const guardedFork = new GuardedMerkleTreeOperations(fork);
125
123
 
126
- const publicTxSimulator = new TelemetryPublicTxSimulator(
124
+ const publicTxSimulator = createPublicTxSimulatorForBlockBuilding(
127
125
  guardedFork,
128
126
  contractsDB,
129
127
  globalVariables,
130
- /*doMerkleOperations=*/ true,
131
- /*skipFeeEnforcement=*/ true,
132
- /*clientInitiatedSimulation=*/ false,
133
128
  this.telemetryClient,
134
129
  );
135
130
 
@@ -157,7 +152,7 @@ export class FullNodeBlockBuilder implements IFullNodeBlockBuilder {
157
152
  };
158
153
  }
159
154
 
160
- private async syncToPreviousBlock(parentBlockNumber: number, timeout: number | undefined) {
155
+ private async syncToPreviousBlock(parentBlockNumber: BlockNumber, timeout: number | undefined) {
161
156
  await retryUntil(
162
157
  () => this.worldState.syncImmediate(parentBlockNumber, true).then(syncedTo => syncedTo >= parentBlockNumber),
163
158
  'sync to previous block',
@@ -174,7 +169,7 @@ export class FullNodeBlockBuilder implements IFullNodeBlockBuilder {
174
169
  opts: PublicProcessorLimits,
175
170
  suppliedFork?: MerkleTreeWriteOperations,
176
171
  ): Promise<BuildBlockResult> {
177
- const parentBlockNumber = globalVariables.blockNumber - 1;
172
+ const parentBlockNumber = BlockNumber(globalVariables.blockNumber - 1);
178
173
  const syncTimeout = opts.deadline ? (opts.deadline.getTime() - this.dateProvider.now()) / 1000 : undefined;
179
174
  await this.syncToPreviousBlock(parentBlockNumber, syncTimeout);
180
175
  const fork = suppliedFork ?? (await this.worldState.fork(parentBlockNumber));
@@ -213,7 +208,7 @@ export class FullNodeBlockBuilder implements IFullNodeBlockBuilder {
213
208
  }
214
209
  }
215
210
 
216
- getFork(blockNumber: number): Promise<MerkleTreeWriteOperations> {
211
+ getFork(blockNumber: BlockNumber): Promise<MerkleTreeWriteOperations> {
217
212
  return this.worldState.fork(blockNumber);
218
213
  }
219
214
  }
@@ -1,4 +1,4 @@
1
- import type { GovernanceProposerContract, RollupContract } from '@aztec/ethereum';
1
+ import type { GovernanceProposerContract, RollupContract } from '@aztec/ethereum/contracts';
2
2
 
3
3
  export { type SequencerConfig } from '@aztec/stdlib/config';
4
4
 
@@ -0,0 +1,21 @@
1
+ import type { SequencerState } from './utils.js';
2
+
3
+ export class SequencerTooSlowError extends Error {
4
+ constructor(
5
+ public readonly proposedState: SequencerState,
6
+ public readonly maxAllowedTime: number,
7
+ public readonly currentTime: number,
8
+ ) {
9
+ super(
10
+ `Too far into slot for ${proposedState} (time into slot ${currentTime}s greater than ${maxAllowedTime}s allowance)`,
11
+ );
12
+ this.name = 'SequencerTooSlowError';
13
+ }
14
+ }
15
+
16
+ export class SequencerInterruptedError extends Error {
17
+ constructor() {
18
+ super(`Sequencer was interrupted`);
19
+ this.name = 'SequencerInterruptedError';
20
+ }
21
+ }
@@ -1,22 +1,21 @@
1
- import type { EthAddress } from '@aztec/aztec.js';
2
- import type { RollupContract } from '@aztec/ethereum';
1
+ import { EthAddress } from '@aztec/aztec.js/addresses';
2
+ import type { RollupContract } from '@aztec/ethereum/contracts';
3
+ import type { SlotNumber } from '@aztec/foundation/branded-types';
3
4
  import {
4
5
  Attributes,
5
- type BatchObservableResult,
6
6
  type Gauge,
7
7
  type Histogram,
8
8
  type Meter,
9
9
  Metrics,
10
- type ObservableGauge,
11
10
  type TelemetryClient,
12
11
  type Tracer,
13
12
  type UpDownCounter,
14
13
  ValueType,
15
14
  } from '@aztec/telemetry-client';
16
15
 
17
- import { formatUnits } from 'viem';
16
+ import { type Hex, formatUnits } from 'viem';
18
17
 
19
- import { type SequencerState, type SequencerStateCallback, sequencerStateToNumber } from './utils.js';
18
+ import type { SequencerState } from './utils.js';
20
19
 
21
20
  export class SequencerMetrics {
22
21
  public readonly tracer: Tracer;
@@ -26,9 +25,6 @@ export class SequencerMetrics {
26
25
  private blockBuildDuration: Histogram;
27
26
  private blockBuildManaPerSecond: Gauge;
28
27
  private stateTransitionBufferDuration: Histogram;
29
- private currentBlockNumber: Gauge;
30
- private currentBlockSize: Gauge;
31
- private blockBuilderInsertions: Histogram;
32
28
 
33
29
  // these are gauges because for individual sequencers building a block is not something that happens often enough to warrant a histogram
34
30
  private timeToCollectAttestations: Gauge;
@@ -36,18 +32,20 @@ export class SequencerMetrics {
36
32
  private requiredAttestions: Gauge;
37
33
  private collectedAttestions: Gauge;
38
34
 
39
- private rewards: ObservableGauge;
35
+ private rewards: Gauge;
40
36
 
41
37
  private slots: UpDownCounter;
42
38
  private filledSlots: UpDownCounter;
43
- private missedSlots: UpDownCounter;
44
39
 
45
- private lastSeenSlot?: bigint;
40
+ private blockProposalFailed: UpDownCounter;
41
+ private blockProposalSuccess: UpDownCounter;
42
+ private blockProposalPrecheckFailed: UpDownCounter;
43
+ private slashingAttempts: UpDownCounter;
44
+
45
+ private lastSeenSlot?: SlotNumber;
46
46
 
47
47
  constructor(
48
48
  client: TelemetryClient,
49
- getState: SequencerStateCallback,
50
- private coinbase: EthAddress,
51
49
  private rollup: RollupContract,
52
50
  name = 'Sequencer',
53
51
  ) {
@@ -78,35 +76,7 @@ export class SequencerMetrics {
78
76
  },
79
77
  );
80
78
 
81
- const currentState = this.meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {
82
- description: 'Current state of the sequencer',
83
- });
84
-
85
- currentState.addCallback(observer => {
86
- observer.observe(sequencerStateToNumber(getState()));
87
- });
88
-
89
- this.currentBlockNumber = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_NUMBER, {
90
- description: 'Current block number',
91
- valueType: ValueType.INT,
92
- });
93
-
94
- this.currentBlockSize = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_SIZE, {
95
- description: 'Current block size',
96
- valueType: ValueType.INT,
97
- });
98
-
99
- this.blockBuilderInsertions = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_INSERTION_TIME, {
100
- description: 'Timer for tree insertions performed by the block builder',
101
- unit: 'us',
102
- valueType: ValueType.INT,
103
- });
104
-
105
79
  // Init gauges and counters
106
- this.setCurrentBlock(0, 0);
107
- this.blockCounter.add(0, {
108
- [Attributes.STATUS]: 'cancelled',
109
- });
110
80
  this.blockCounter.add(0, {
111
81
  [Attributes.STATUS]: 'failed',
112
82
  });
@@ -114,7 +84,7 @@ export class SequencerMetrics {
114
84
  [Attributes.STATUS]: 'built',
115
85
  });
116
86
 
117
- this.rewards = this.meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS, {
87
+ this.rewards = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS, {
118
88
  valueType: ValueType.DOUBLE,
119
89
  description: 'The rewards earned',
120
90
  });
@@ -124,16 +94,15 @@ export class SequencerMetrics {
124
94
  description: 'The number of slots this sequencer was selected for',
125
95
  });
126
96
 
97
+ /**
98
+ * NOTE: we do not track missed slots as a separate metric. That would be difficult to determine
99
+ * Instead, use a computed metric, `slots - filledSlots` to get the number of slots a sequencer has missed.
100
+ */
127
101
  this.filledSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_FILLED_SLOT_COUNT, {
128
102
  valueType: ValueType.INT,
129
103
  description: 'The number of slots this sequencer has filled',
130
104
  });
131
105
 
132
- this.missedSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_MISSED_SLOT_COUNT, {
133
- valueType: ValueType.INT,
134
- description: 'The number of slots this sequencer has missed to fill',
135
- });
136
-
137
106
  this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_COLLECT_ATTESTATIONS_DURATION, {
138
107
  description: 'The time spent collecting attestations from committee members',
139
108
  unit: 'ms',
@@ -158,29 +127,30 @@ export class SequencerMetrics {
158
127
  valueType: ValueType.INT,
159
128
  description: 'The minimum number of attestations required to publish a block',
160
129
  });
161
- }
162
-
163
- public setCoinbase(coinbase: EthAddress) {
164
- this.coinbase = coinbase;
165
- }
166
130
 
167
- public start() {
168
- this.meter.addBatchObservableCallback(this.observe, [this.rewards]);
169
- }
131
+ this.blockProposalFailed = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT, {
132
+ valueType: ValueType.INT,
133
+ description: 'The number of times block proposal failed (including validation builds)',
134
+ });
170
135
 
171
- public stop() {
172
- this.meter.removeBatchObservableCallback(this.observe, [this.rewards]);
173
- }
136
+ this.blockProposalSuccess = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_PROPOSAL_SUCCESS_COUNT, {
137
+ valueType: ValueType.INT,
138
+ description: 'The number of times block proposal succeeded (including validation builds)',
139
+ });
174
140
 
175
- private observe = async (observer: BatchObservableResult): Promise<void> => {
176
- let rewards = 0n;
177
- rewards = await this.rollup.getSequencerRewards(this.coinbase);
141
+ this.blockProposalPrecheckFailed = this.meter.createUpDownCounter(
142
+ Metrics.SEQUENCER_BLOCK_PROPOSAL_PRECHECK_FAILED_COUNT,
143
+ {
144
+ valueType: ValueType.INT,
145
+ description: 'The number of times block proposal pre-build checks failed',
146
+ },
147
+ );
178
148
 
179
- const fmt = parseFloat(formatUnits(rewards, 18));
180
- observer.observe(this.rewards, fmt, {
181
- [Attributes.COINBASE]: this.coinbase.toString(),
149
+ this.slashingAttempts = this.meter.createUpDownCounter(Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT, {
150
+ valueType: ValueType.INT,
151
+ description: 'The number of slashing action attempts',
182
152
  });
183
- };
153
+ }
184
154
 
185
155
  public recordRequiredAttestations(requiredAttestationsCount: number, allowanceMs: number) {
186
156
  this.requiredAttestions.record(requiredAttestationsCount);
@@ -196,17 +166,6 @@ export class SequencerMetrics {
196
166
  this.timeToCollectAttestations.record(Math.ceil(durationMs));
197
167
  }
198
168
 
199
- recordBlockBuilderTreeInsertions(timeUs: number) {
200
- this.blockBuilderInsertions.record(Math.ceil(timeUs));
201
- }
202
-
203
- recordCancelledBlock() {
204
- this.blockCounter.add(1, {
205
- [Attributes.STATUS]: 'cancelled',
206
- });
207
- this.setCurrentBlock(0, 0);
208
- }
209
-
210
169
  recordBuiltBlock(buildDurationMs: number, totalMana: number) {
211
170
  this.blockCounter.add(1, {
212
171
  [Attributes.STATUS]: 'built',
@@ -219,11 +178,6 @@ export class SequencerMetrics {
219
178
  this.blockCounter.add(1, {
220
179
  [Attributes.STATUS]: 'failed',
221
180
  });
222
- this.setCurrentBlock(0, 0);
223
- }
224
-
225
- recordNewBlock(blockNumber: number, txCount: number) {
226
- this.setCurrentBlock(blockNumber, txCount);
227
181
  }
228
182
 
229
183
  recordStateTransitionBufferMs(durationMs: number, state: SequencerState) {
@@ -232,36 +186,55 @@ export class SequencerMetrics {
232
186
  });
233
187
  }
234
188
 
235
- observeSlotChange(slot: bigint | undefined, proposer: string) {
189
+ incOpenSlot(slot: SlotNumber, proposer: string) {
236
190
  // sequencer went through the loop a second time. Noop
237
191
  if (slot === this.lastSeenSlot) {
238
192
  return;
239
193
  }
240
194
 
241
- if (typeof this.lastSeenSlot === 'bigint') {
242
- this.missedSlots.add(1, {
243
- [Attributes.BLOCK_PROPOSER]: proposer,
244
- });
245
- }
246
-
247
- if (typeof slot === 'bigint') {
248
- this.slots.add(1, {
249
- [Attributes.BLOCK_PROPOSER]: proposer,
250
- });
251
- }
195
+ this.slots.add(1, {
196
+ [Attributes.BLOCK_PROPOSER]: proposer,
197
+ });
252
198
 
253
199
  this.lastSeenSlot = slot;
254
200
  }
255
201
 
256
- incFilledSlot(proposer: string) {
202
+ async incFilledSlot(proposer: string, coinbase: Hex | EthAddress | undefined): Promise<void> {
257
203
  this.filledSlots.add(1, {
258
204
  [Attributes.BLOCK_PROPOSER]: proposer,
259
205
  });
260
206
  this.lastSeenSlot = undefined;
207
+
208
+ if (coinbase) {
209
+ try {
210
+ const rewards = await this.rollup.getSequencerRewards(coinbase);
211
+ const fmt = parseFloat(formatUnits(rewards, 18));
212
+ this.rewards.record(fmt, {
213
+ [Attributes.COINBASE]: coinbase.toString(),
214
+ });
215
+ } catch {
216
+ // no-op
217
+ }
218
+ }
219
+ }
220
+
221
+ recordBlockProposalFailed(reason?: string) {
222
+ this.blockProposalFailed.add(1, {
223
+ ...(reason && { [Attributes.ERROR_TYPE]: reason }),
224
+ });
225
+ }
226
+
227
+ recordBlockProposalSuccess() {
228
+ this.blockProposalSuccess.add(1);
229
+ }
230
+
231
+ recordBlockProposalPrecheckFailed(checkType: string) {
232
+ this.blockProposalPrecheckFailed.add(1, {
233
+ [Attributes.ERROR_TYPE]: checkType,
234
+ });
261
235
  }
262
236
 
263
- private setCurrentBlock(blockNumber: number, txCount: number) {
264
- this.currentBlockNumber.record(blockNumber);
265
- this.currentBlockSize.record(txCount);
237
+ recordSlashingAttempt(actionCount: number) {
238
+ this.slashingAttempts.add(actionCount);
266
239
  }
267
240
  }