@aztec/validator-client 0.0.1-commit.b2a5d0dd1 → 0.0.1-commit.b3d3157a
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/README.md +10 -9
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +15 -5
- package/dest/duties/validation_service.d.ts +6 -5
- package/dest/duties/validation_service.d.ts.map +1 -1
- package/dest/duties/validation_service.js +24 -18
- package/dest/factory.d.ts +4 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +8 -3
- package/dest/proposal_handler.d.ts +38 -12
- package/dest/proposal_handler.d.ts.map +1 -1
- package/dest/proposal_handler.js +232 -134
- package/dest/validator.d.ts +15 -2
- package/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +182 -42
- package/package.json +19 -19
- package/src/config.ts +15 -4
- package/src/duties/validation_service.ts +38 -21
- package/src/factory.ts +10 -0
- package/src/proposal_handler.ts +278 -159
- package/src/validator.ts +227 -52
package/dest/validator.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { P2P, PeerId } from '@aztec/p2p';
|
|
|
11
11
|
import { type Watcher, type WatcherEmitter } from '@aztec/slasher';
|
|
12
12
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
13
13
|
import type { CommitteeAttestationsAndSigners, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block';
|
|
14
|
+
import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint';
|
|
14
15
|
import type { ITxProvider, Validator, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
15
16
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
16
17
|
import { type BlockProposal, type BlockProposalOptions, type CheckpointAttestation, CheckpointProposal, type CheckpointProposalCore, type CheckpointProposalOptions } from '@aztec/stdlib/p2p';
|
|
@@ -54,18 +55,25 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
|
|
|
54
55
|
/** Tracks the last epoch in which each attester successfully submitted at least one attestation. */
|
|
55
56
|
private lastAttestedEpochByAttester;
|
|
56
57
|
private proposersOfInvalidBlocks;
|
|
58
|
+
private slotsWithInvalidProposals;
|
|
59
|
+
private invalidCheckpointProposalOffenseKeys;
|
|
60
|
+
private badAttestationOffenseKeys;
|
|
61
|
+
private slotsWithProposalEquivocation;
|
|
57
62
|
/** Tracks the last checkpoint proposal we attested to, to prevent equivocation. */
|
|
58
63
|
private lastAttestedProposal?;
|
|
59
64
|
protected constructor(keyStore: ExtendedValidatorKeyStore, epochCache: EpochCache, p2pClient: P2P, proposalHandler: ProposalHandler, blockSource: L2BlockSource, checkpointsBuilder: FullNodeCheckpointsBuilder, worldState: WorldStateSynchronizer, l1ToL2MessageSource: L1ToL2MessageSource, config: ValidatorClientFullConfig, blobClient: BlobClientInterface, slashingProtectionSigner: ValidatorHASigner, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: Logger);
|
|
60
65
|
static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager, logger?: Logger): void;
|
|
61
66
|
private handleEpochCommitteeUpdate;
|
|
62
|
-
static new(config: ValidatorClientFullConfig, checkpointsBuilder: FullNodeCheckpointsBuilder, worldState: WorldStateSynchronizer, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource & L2BlockSink, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: ITxProvider, keyStoreManager: KeystoreManager, blobClient: BlobClientInterface, dateProvider?: DateProvider, telemetry?: TelemetryClient, slashingProtectionDb?: SlashingProtectionDatabase): Promise<ValidatorClient>;
|
|
67
|
+
static new(config: ValidatorClientFullConfig, checkpointsBuilder: FullNodeCheckpointsBuilder, worldState: WorldStateSynchronizer, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource & L2BlockSink, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: ITxProvider, keyStoreManager: KeystoreManager, blobClient: BlobClientInterface, reexecutionTracker: CheckpointReexecutionTracker, dateProvider?: DateProvider, telemetry?: TelemetryClient, slashingProtectionDb?: SlashingProtectionDatabase): Promise<ValidatorClient>;
|
|
63
68
|
getValidatorAddresses(): EthAddress[];
|
|
64
69
|
getProposalHandler(): ProposalHandler;
|
|
65
70
|
signWithAddress(addr: EthAddress, msg: TypedDataDefinition, context: SigningContext): Promise<Signature>;
|
|
71
|
+
private getSignatureContext;
|
|
66
72
|
getCoinbaseForAttestor(attestor: EthAddress): EthAddress;
|
|
67
73
|
getFeeRecipientForAttestor(attestor: EthAddress): AztecAddress;
|
|
68
74
|
getConfig(): ValidatorClientFullConfig;
|
|
75
|
+
hasProposalEquivocation(slotNumber: SlotNumber): boolean;
|
|
76
|
+
hasInvalidProposals(slotNumber: SlotNumber): boolean;
|
|
69
77
|
updateConfig(config: Partial<ValidatorClientFullConfig>): void;
|
|
70
78
|
reloadKeystore(newManager: KeystoreManager): void;
|
|
71
79
|
start(): Promise<void>;
|
|
@@ -96,6 +104,11 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
|
|
|
96
104
|
*/
|
|
97
105
|
protected uploadBlobsForCheckpoint(proposal: CheckpointProposalCore, proposalInfo: LogData): Promise<void>;
|
|
98
106
|
private slashInvalidBlock;
|
|
107
|
+
private handleInvalidCheckpointProposal;
|
|
108
|
+
private slashInvalidCheckpointProposal;
|
|
109
|
+
private markInvalidProposalSlot;
|
|
110
|
+
private handleCheckpointAttestation;
|
|
111
|
+
private slashAttestedToInvalidCheckpointProposal;
|
|
99
112
|
/**
|
|
100
113
|
* Handle detection of a duplicate proposal (equivocation).
|
|
101
114
|
* Emits a slash event when a proposer sends multiple proposals for the same position.
|
|
@@ -115,4 +128,4 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
|
|
|
115
128
|
private handleAuthRequest;
|
|
116
129
|
}
|
|
117
130
|
export {};
|
|
118
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
131
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFckUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLGdCQUFnQixFQUFlLHFCQUFxQixFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25ILE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVqRSxPQUFPLEVBQUUsS0FBSyxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFHaEYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFtRCxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRS9GLE9BQU8sRUFJTCxLQUFLLE9BQU8sRUFDWixLQUFLLGNBQWMsRUFFcEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSwrQkFBK0IsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkcsT0FBTyxLQUFLLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU3RSxPQUFPLEtBQUssRUFDVixXQUFXLEVBQ1gsU0FBUyxFQUNULHlC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
|
package/dest/validator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAe,qBAAqB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACnH,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
|
package/dest/validator.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { getBlobsPerL1Block } from '@aztec/blob-lib';
|
|
2
2
|
import { CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { FifoSet } from '@aztec/foundation/fifo-set';
|
|
3
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
5
6
|
import { sleep } from '@aztec/foundation/sleep';
|
|
6
7
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
7
8
|
import { AuthRequest, AuthResponse, BlockProposalValidator, ReqRespSubProtocol } from '@aztec/p2p';
|
|
8
|
-
import { OffenseType, WANT_TO_SLASH_EVENT } from '@aztec/slasher';
|
|
9
|
+
import { OffenseType, WANT_TO_CLEAR_SLASH_EVENT, WANT_TO_SLASH_EVENT, getOffenseTypeName } from '@aztec/slasher';
|
|
9
10
|
import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
|
|
10
11
|
import { AttestationTimeoutError } from '@aztec/stdlib/validators';
|
|
11
12
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
@@ -20,11 +21,36 @@ import { ProposalHandler } from './proposal_handler.js';
|
|
|
20
21
|
// We maintain a set of proposers who have proposed invalid blocks.
|
|
21
22
|
// Just cap the set to avoid unbounded growth.
|
|
22
23
|
const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
24
|
+
const MAX_TRACKED_INVALID_PROPOSAL_SLOTS = 1000;
|
|
25
|
+
const MAX_TRACKED_INVALID_CHECKPOINT_PROPOSALS = 1000;
|
|
26
|
+
const MAX_TRACKED_BAD_ATTESTATIONS = 10_000;
|
|
23
27
|
// What errors from the block proposal handler result in slashing
|
|
24
28
|
const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
25
29
|
'state_mismatch',
|
|
26
|
-
'failed_txs'
|
|
30
|
+
'failed_txs',
|
|
31
|
+
'global_variables_mismatch',
|
|
32
|
+
'invalid_proposal',
|
|
33
|
+
'parent_block_wrong_slot',
|
|
34
|
+
'in_hash_mismatch'
|
|
27
35
|
];
|
|
36
|
+
const SLASHABLE_CHECKPOINT_PROPOSAL_VALIDATION_RESULT = {
|
|
37
|
+
// enabled
|
|
38
|
+
['invalid_fee_asset_price_modifier']: true,
|
|
39
|
+
['checkpoint_header_mismatch']: true,
|
|
40
|
+
// These late mismatches should normally be caught by earlier checks, but if reached after validating the local
|
|
41
|
+
// checkpoint inputs, the proposer-signed payload disagrees with deterministic recomputation.
|
|
42
|
+
['archive_mismatch']: true,
|
|
43
|
+
['out_hash_mismatch']: true,
|
|
44
|
+
['no_blocks_for_slot']: true,
|
|
45
|
+
['too_many_blocks_in_checkpoint']: true,
|
|
46
|
+
['checkpoint_validation_failed']: true,
|
|
47
|
+
['last_block_archive_mismatch']: true,
|
|
48
|
+
// disabled
|
|
49
|
+
['invalid_signature']: false,
|
|
50
|
+
['last_block_not_found']: false,
|
|
51
|
+
['block_fetch_error']: false,
|
|
52
|
+
['checkpoint_already_published']: false
|
|
53
|
+
};
|
|
28
54
|
/**
|
|
29
55
|
* Validator Client
|
|
30
56
|
*/ export class ValidatorClient extends EventEmitter {
|
|
@@ -52,14 +78,19 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
52
78
|
epochCacheUpdateLoop;
|
|
53
79
|
/** Tracks the last epoch in which each attester successfully submitted at least one attestation. */ lastAttestedEpochByAttester;
|
|
54
80
|
proposersOfInvalidBlocks;
|
|
81
|
+
slotsWithInvalidProposals;
|
|
82
|
+
invalidCheckpointProposalOffenseKeys;
|
|
83
|
+
badAttestationOffenseKeys;
|
|
84
|
+
slotsWithProposalEquivocation;
|
|
55
85
|
/** Tracks the last checkpoint proposal we attested to, to prevent equivocation. */ lastAttestedProposal;
|
|
56
86
|
constructor(keyStore, epochCache, p2pClient, proposalHandler, blockSource, checkpointsBuilder, worldState, l1ToL2MessageSource, config, blobClient, slashingProtectionSigner, dateProvider = new DateProvider(), telemetry = getTelemetryClient(), log = createLogger('validator')){
|
|
57
|
-
super(), this.keyStore = keyStore, this.epochCache = epochCache, this.p2pClient = p2pClient, this.proposalHandler = proposalHandler, this.blockSource = blockSource, this.checkpointsBuilder = checkpointsBuilder, this.worldState = worldState, this.l1ToL2MessageSource = l1ToL2MessageSource, this.config = config, this.blobClient = blobClient, this.slashingProtectionSigner = slashingProtectionSigner, this.dateProvider = dateProvider, this.hasRegisteredHandlers = false, this.lastAttestedEpochByAttester = new Map(), this.proposersOfInvalidBlocks =
|
|
87
|
+
super(), this.keyStore = keyStore, this.epochCache = epochCache, this.p2pClient = p2pClient, this.proposalHandler = proposalHandler, this.blockSource = blockSource, this.checkpointsBuilder = checkpointsBuilder, this.worldState = worldState, this.l1ToL2MessageSource = l1ToL2MessageSource, this.config = config, this.blobClient = blobClient, this.slashingProtectionSigner = slashingProtectionSigner, this.dateProvider = dateProvider, this.hasRegisteredHandlers = false, this.lastAttestedEpochByAttester = new Map(), this.proposersOfInvalidBlocks = FifoSet.withLimit(MAX_PROPOSERS_OF_INVALID_BLOCKS), this.slotsWithInvalidProposals = FifoSet.withLimit(MAX_TRACKED_INVALID_PROPOSAL_SLOTS), this.invalidCheckpointProposalOffenseKeys = FifoSet.withLimit(MAX_TRACKED_INVALID_CHECKPOINT_PROPOSALS), this.badAttestationOffenseKeys = FifoSet.withLimit(MAX_TRACKED_BAD_ATTESTATIONS), this.slotsWithProposalEquivocation = FifoSet.withLimit(MAX_TRACKED_INVALID_PROPOSAL_SLOTS);
|
|
58
88
|
// Create child logger with fisherman prefix if in fisherman mode
|
|
59
89
|
this.log = config.fishermanMode ? log.createChild('[FISHERMAN]') : log;
|
|
60
90
|
this.tracer = telemetry.getTracer('Validator');
|
|
61
91
|
this.metrics = new ValidatorMetrics(telemetry);
|
|
62
|
-
this.validationService = new ValidationService(keyStore, this.log.createChild('validation-service'));
|
|
92
|
+
this.validationService = new ValidationService(keyStore, this.getSignatureContext(), this.log.createChild('validation-service'));
|
|
93
|
+
this.proposalHandler.setCheckpointProposalValidationFailureCallback((proposal, result, proposalInfo)=>this.handleInvalidCheckpointProposal(proposal, result, proposalInfo));
|
|
63
94
|
// Refresh epoch cache every second to trigger alert if participation in committee changes
|
|
64
95
|
this.epochCacheUpdateLoop = new RunningPromise(this.handleEpochCommitteeUpdate.bind(this), this.log, 1000);
|
|
65
96
|
const myAddresses = this.getValidatorAddresses();
|
|
@@ -109,13 +140,19 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
109
140
|
this.log.error(`Error updating epoch committee`, err);
|
|
110
141
|
}
|
|
111
142
|
}
|
|
112
|
-
static async new(config, checkpointsBuilder, worldState, epochCache, p2pClient, blockSource, l1ToL2MessageSource, txProvider, keyStoreManager, blobClient, dateProvider = new DateProvider(), telemetry = getTelemetryClient(), slashingProtectionDb) {
|
|
143
|
+
static async new(config, checkpointsBuilder, worldState, epochCache, p2pClient, blockSource, l1ToL2MessageSource, txProvider, keyStoreManager, blobClient, reexecutionTracker, dateProvider = new DateProvider(), telemetry = getTelemetryClient(), slashingProtectionDb) {
|
|
113
144
|
const metrics = new ValidatorMetrics(telemetry);
|
|
114
145
|
const blockProposalValidator = new BlockProposalValidator(epochCache, {
|
|
115
146
|
txsPermitted: !config.disableTransactions,
|
|
116
|
-
maxTxsPerBlock: config.validateMaxTxsPerBlock
|
|
147
|
+
maxTxsPerBlock: config.validateMaxTxsPerBlock,
|
|
148
|
+
maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
|
|
149
|
+
skipSlotValidation: config.skipProposalSlotValidation,
|
|
150
|
+
signatureContext: {
|
|
151
|
+
chainId: config.l1ChainId,
|
|
152
|
+
rollupAddress: config.rollupAddress
|
|
153
|
+
}
|
|
117
154
|
});
|
|
118
|
-
const proposalHandler = new ProposalHandler(checkpointsBuilder, worldState, blockSource, l1ToL2MessageSource, txProvider, blockProposalValidator, epochCache, config, blobClient, metrics, dateProvider, telemetry, undefined);
|
|
155
|
+
const proposalHandler = new ProposalHandler(checkpointsBuilder, worldState, blockSource, l1ToL2MessageSource, txProvider, blockProposalValidator, epochCache, config, blobClient, reexecutionTracker, metrics, dateProvider, telemetry, undefined);
|
|
119
156
|
const nodeKeystoreAdapter = NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager);
|
|
120
157
|
let slashingProtectionSigner;
|
|
121
158
|
if (slashingProtectionDb) {
|
|
@@ -156,6 +193,12 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
156
193
|
signWithAddress(addr, msg, context) {
|
|
157
194
|
return this.keyStore.signTypedDataWithAddress(addr, msg, context);
|
|
158
195
|
}
|
|
196
|
+
getSignatureContext() {
|
|
197
|
+
return {
|
|
198
|
+
chainId: this.config.l1ChainId,
|
|
199
|
+
rollupAddress: this.config.rollupAddress
|
|
200
|
+
};
|
|
201
|
+
}
|
|
159
202
|
getCoinbaseForAttestor(attestor) {
|
|
160
203
|
return this.keyStore.getCoinbaseAddress(attestor);
|
|
161
204
|
}
|
|
@@ -165,16 +208,23 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
165
208
|
getConfig() {
|
|
166
209
|
return this.config;
|
|
167
210
|
}
|
|
211
|
+
hasProposalEquivocation(slotNumber) {
|
|
212
|
+
return this.slotsWithProposalEquivocation.has(slotNumber);
|
|
213
|
+
}
|
|
214
|
+
hasInvalidProposals(slotNumber) {
|
|
215
|
+
return this.slotsWithInvalidProposals.has(slotNumber);
|
|
216
|
+
}
|
|
168
217
|
updateConfig(config) {
|
|
169
218
|
this.config = {
|
|
170
219
|
...this.config,
|
|
171
220
|
...config
|
|
172
221
|
};
|
|
222
|
+
this.proposalHandler.updateConfig(config);
|
|
173
223
|
}
|
|
174
224
|
reloadKeystore(newManager) {
|
|
175
225
|
const newAdapter = NodeKeystoreAdapter.fromKeyStoreManager(newManager);
|
|
176
226
|
this.keyStore = new HAKeyStore(newAdapter, this.slashingProtectionSigner);
|
|
177
|
-
this.validationService = new ValidationService(this.keyStore, this.log.createChild('validation-service'));
|
|
227
|
+
this.validationService = new ValidationService(this.keyStore, this.getSignatureContext(), this.log.createChild('validation-service'));
|
|
178
228
|
}
|
|
179
229
|
async start() {
|
|
180
230
|
if (this.epochCacheUpdateLoop.isRunning()) {
|
|
@@ -216,6 +266,9 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
216
266
|
this.p2pClient.registerDuplicateAttestationCallback((info)=>{
|
|
217
267
|
this.handleDuplicateAttestation(info);
|
|
218
268
|
});
|
|
269
|
+
this.p2pClient.registerCheckpointAttestationCallback((attestation)=>{
|
|
270
|
+
this.handleCheckpointAttestation(attestation);
|
|
271
|
+
});
|
|
219
272
|
const myAddresses = this.getValidatorAddresses();
|
|
220
273
|
this.p2pClient.registerThisValidatorAddresses(myAddresses);
|
|
221
274
|
await this.p2pClient.addReqRespSubProtocol(ReqRespSubProtocol.AUTH, this.handleAuthRequest.bind(this));
|
|
@@ -255,11 +308,8 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
255
308
|
txHashes: proposal.txHashes.map((t)=>t.toString()),
|
|
256
309
|
fishermanMode: this.config.fishermanMode || false
|
|
257
310
|
});
|
|
258
|
-
// Reexecute
|
|
259
|
-
|
|
260
|
-
const { slashBroadcastedInvalidBlockPenalty, alwaysReexecuteBlockProposals, fishermanMode } = this.config;
|
|
261
|
-
const shouldReexecute = fishermanMode || slashBroadcastedInvalidBlockPenalty > 0n || partOfCommittee || alwaysReexecuteBlockProposals || this.blobClient.canUpload();
|
|
262
|
-
const validationResult = await this.proposalHandler.handleBlockProposal(proposal, proposalSender, !!shouldReexecute && !escapeHatchOpen);
|
|
311
|
+
// Reexecute outside the escape hatch so slashing observers can detect invalid proposals even when penalties are 0.
|
|
312
|
+
const validationResult = await this.proposalHandler.handleBlockProposal(proposal, proposalSender, !escapeHatchOpen);
|
|
263
313
|
if (!validationResult.isValid) {
|
|
264
314
|
const reason = validationResult.reason || 'unknown';
|
|
265
315
|
this.log.warn(`Block proposal validation failed: ${reason}`, proposalInfo);
|
|
@@ -277,10 +327,14 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
277
327
|
// Node issues so we can't validate
|
|
278
328
|
this.metrics.incFailedAttestationsNodeIssue(1, reason, partOfCommittee);
|
|
279
329
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
330
|
+
if (!escapeHatchOpen && validationResult.reason && SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT.includes(validationResult.reason)) {
|
|
331
|
+
this.log.info(`Detected invalid block proposal offense`, {
|
|
332
|
+
...proposalInfo,
|
|
333
|
+
amount: this.config.slashBroadcastedInvalidBlockPenalty,
|
|
334
|
+
offenseType: getOffenseTypeName(OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL)
|
|
335
|
+
});
|
|
283
336
|
this.slashInvalidBlock(proposal);
|
|
337
|
+
this.markInvalidProposalSlot(proposal.slotNumber);
|
|
284
338
|
}
|
|
285
339
|
return false;
|
|
286
340
|
}
|
|
@@ -309,6 +363,10 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
309
363
|
this.log.warn(`Escape hatch open for slot ${proposalSlotNumber}, skipping checkpoint attestation handling`);
|
|
310
364
|
return undefined;
|
|
311
365
|
}
|
|
366
|
+
// Early-out for equivocation: refuses if we've already attested to a higher slot.
|
|
367
|
+
if (!this.shouldAttestToSlot(proposalSlotNumber)) {
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
312
370
|
// Ignore proposals from ourselves (may happen in HA setups)
|
|
313
371
|
if (proposer && this.getValidatorAddresses().some((addr)=>addr.equals(proposer))) {
|
|
314
372
|
this.log.debug(`Ignoring block proposal from self for slot ${proposalSlotNumber}`, {
|
|
@@ -420,7 +478,9 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
420
478
|
* Uploads blobs for a checkpoint to the filestore (fire and forget).
|
|
421
479
|
*/ async uploadBlobsForCheckpoint(proposal, proposalInfo) {
|
|
422
480
|
try {
|
|
423
|
-
const lastBlockHeader = await this.blockSource.
|
|
481
|
+
const lastBlockHeader = (await this.blockSource.getBlockData({
|
|
482
|
+
archive: proposal.archive
|
|
483
|
+
}))?.header;
|
|
424
484
|
if (!lastBlockHeader) {
|
|
425
485
|
this.log.warn(`Failed to get last block header for blob upload`, proposalInfo);
|
|
426
486
|
return;
|
|
@@ -448,11 +508,6 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
448
508
|
this.log.warn(`Cannot slash proposal with invalid signature`);
|
|
449
509
|
return;
|
|
450
510
|
}
|
|
451
|
-
// Trim the set if it's too big.
|
|
452
|
-
if (this.proposersOfInvalidBlocks.size > MAX_PROPOSERS_OF_INVALID_BLOCKS) {
|
|
453
|
-
// remove oldest proposer. `values` is guaranteed to be in insertion order.
|
|
454
|
-
this.proposersOfInvalidBlocks.delete(this.proposersOfInvalidBlocks.values().next().value);
|
|
455
|
-
}
|
|
456
511
|
this.proposersOfInvalidBlocks.add(proposer.toString());
|
|
457
512
|
this.emit(WANT_TO_SLASH_EVENT, [
|
|
458
513
|
{
|
|
@@ -463,17 +518,95 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
463
518
|
}
|
|
464
519
|
]);
|
|
465
520
|
}
|
|
521
|
+
handleInvalidCheckpointProposal(proposal, result, proposalInfo) {
|
|
522
|
+
if (!SLASHABLE_CHECKPOINT_PROPOSAL_VALIDATION_RESULT[result.reason]) {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
this.markInvalidProposalSlot(proposal.slotNumber);
|
|
526
|
+
if (this.slashInvalidCheckpointProposal(proposal)) {
|
|
527
|
+
this.log.info(`Detected invalid checkpoint proposal offense`, {
|
|
528
|
+
...proposalInfo,
|
|
529
|
+
reason: result.reason,
|
|
530
|
+
amount: this.config.slashBroadcastedInvalidCheckpointProposalPenalty,
|
|
531
|
+
offenseType: getOffenseTypeName(OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL)
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
slashInvalidCheckpointProposal(proposal) {
|
|
536
|
+
const proposer = proposal.getSender();
|
|
537
|
+
if (!proposer) {
|
|
538
|
+
this.log.warn(`Cannot slash checkpoint proposal with invalid signature`, {
|
|
539
|
+
slotNumber: proposal.slotNumber,
|
|
540
|
+
archive: proposal.archive.toString()
|
|
541
|
+
});
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
const offenseType = OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL;
|
|
545
|
+
const offenseKey = `${proposer.toString()}:${offenseType}:${proposal.slotNumber}`;
|
|
546
|
+
if (!this.invalidCheckpointProposalOffenseKeys.addIfAbsent(offenseKey)) {
|
|
547
|
+
return false;
|
|
548
|
+
}
|
|
549
|
+
this.emit(WANT_TO_SLASH_EVENT, [
|
|
550
|
+
{
|
|
551
|
+
validator: proposer,
|
|
552
|
+
amount: this.config.slashBroadcastedInvalidCheckpointProposalPenalty,
|
|
553
|
+
offenseType,
|
|
554
|
+
epochOrSlot: BigInt(proposal.slotNumber)
|
|
555
|
+
}
|
|
556
|
+
]);
|
|
557
|
+
return true;
|
|
558
|
+
}
|
|
559
|
+
markInvalidProposalSlot(slotNumber) {
|
|
560
|
+
this.slotsWithInvalidProposals.add(slotNumber);
|
|
561
|
+
}
|
|
562
|
+
handleCheckpointAttestation(attestation) {
|
|
563
|
+
const slotNumber = attestation.slotNumber;
|
|
564
|
+
if (!this.slotsWithInvalidProposals.has(slotNumber) || this.slotsWithProposalEquivocation.has(slotNumber)) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
const attester = attestation.getSender();
|
|
568
|
+
if (!attester) {
|
|
569
|
+
this.log.warn(`Cannot slash checkpoint attestation with invalid signature`, {
|
|
570
|
+
slotNumber,
|
|
571
|
+
archive: attestation.archive.toString()
|
|
572
|
+
});
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
this.slashAttestedToInvalidCheckpointProposal(slotNumber, attester);
|
|
576
|
+
}
|
|
577
|
+
slashAttestedToInvalidCheckpointProposal(slotNumber, attester) {
|
|
578
|
+
const offenseKey = `${attester.toString()}:${OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL}:${slotNumber}`;
|
|
579
|
+
if (!this.badAttestationOffenseKeys.addIfAbsent(offenseKey)) {
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
this.log.info(`Detected attestation to invalid checkpoint proposal offense`, {
|
|
583
|
+
attester: attester.toString(),
|
|
584
|
+
slotNumber,
|
|
585
|
+
amount: this.config.slashAttestInvalidCheckpointProposalPenalty,
|
|
586
|
+
offenseType: getOffenseTypeName(OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL)
|
|
587
|
+
});
|
|
588
|
+
this.emit(WANT_TO_SLASH_EVENT, [
|
|
589
|
+
{
|
|
590
|
+
validator: attester,
|
|
591
|
+
amount: this.config.slashAttestInvalidCheckpointProposalPenalty,
|
|
592
|
+
offenseType: OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL,
|
|
593
|
+
epochOrSlot: BigInt(slotNumber)
|
|
594
|
+
}
|
|
595
|
+
]);
|
|
596
|
+
}
|
|
466
597
|
/**
|
|
467
598
|
* Handle detection of a duplicate proposal (equivocation).
|
|
468
599
|
* Emits a slash event when a proposer sends multiple proposals for the same position.
|
|
469
600
|
*/ handleDuplicateProposal(info) {
|
|
470
601
|
const { slot, proposer, type } = info;
|
|
471
|
-
this.
|
|
602
|
+
this.slotsWithProposalEquivocation.add(slot);
|
|
603
|
+
this.log.info(`Detected duplicate ${type} proposal offense from ${proposer.toString()} at slot ${slot}`, {
|
|
472
604
|
proposer: proposer.toString(),
|
|
473
605
|
slot,
|
|
474
|
-
type
|
|
606
|
+
type,
|
|
607
|
+
amount: this.config.slashDuplicateProposalPenalty,
|
|
608
|
+
offenseType: getOffenseTypeName(OffenseType.DUPLICATE_PROPOSAL)
|
|
475
609
|
});
|
|
476
|
-
// Emit slash event
|
|
477
610
|
this.emit(WANT_TO_SLASH_EVENT, [
|
|
478
611
|
{
|
|
479
612
|
validator: proposer,
|
|
@@ -482,15 +615,23 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
482
615
|
epochOrSlot: BigInt(slot)
|
|
483
616
|
}
|
|
484
617
|
]);
|
|
618
|
+
this.emit(WANT_TO_CLEAR_SLASH_EVENT, [
|
|
619
|
+
{
|
|
620
|
+
offenseType: OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL,
|
|
621
|
+
epochOrSlot: BigInt(slot)
|
|
622
|
+
}
|
|
623
|
+
]);
|
|
485
624
|
}
|
|
486
625
|
/**
|
|
487
626
|
* Handle detection of a duplicate attestation (equivocation).
|
|
488
627
|
* Emits a slash event when an attester signs attestations for different proposals at the same slot.
|
|
489
628
|
*/ handleDuplicateAttestation(info) {
|
|
490
629
|
const { slot, attester } = info;
|
|
491
|
-
this.log.
|
|
630
|
+
this.log.info(`Detected duplicate attestation offense from ${attester.toString()} at slot ${slot}`, {
|
|
492
631
|
attester: attester.toString(),
|
|
493
|
-
slot
|
|
632
|
+
slot,
|
|
633
|
+
amount: this.config.slashDuplicateAttestationPenalty,
|
|
634
|
+
offenseType: getOffenseTypeName(OffenseType.DUPLICATE_ATTESTATION)
|
|
494
635
|
});
|
|
495
636
|
this.emit(WANT_TO_SLASH_EVENT, [
|
|
496
637
|
{
|
|
@@ -514,7 +655,7 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
514
655
|
this.log.info(`Assembling block proposal for block ${blockHeader.globalVariables.blockNumber} slot ${blockHeader.globalVariables.slotNumber}`);
|
|
515
656
|
const newProposal = await this.validationService.createBlockProposal(blockHeader, checkpointNumber, indexWithinCheckpoint, inHash, archive, txs, proposerAddress, {
|
|
516
657
|
...options,
|
|
517
|
-
broadcastInvalidBlockProposal: this.config.broadcastInvalidBlockProposal
|
|
658
|
+
broadcastInvalidBlockProposal: options.broadcastInvalidBlockProposal || this.config.broadcastInvalidBlockProposal
|
|
518
659
|
});
|
|
519
660
|
this.lastProposedBlock = newProposal;
|
|
520
661
|
return newProposal;
|
|
@@ -531,6 +672,13 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
531
672
|
this.log.info(`Assembling checkpoint proposal for slot ${checkpointHeader.slotNumber}`);
|
|
532
673
|
const newProposal = await this.validationService.createCheckpointProposal(checkpointHeader, archive, checkpointNumber, feeAssetPriceModifier, lastBlockProposal, proposerAddress, options);
|
|
533
674
|
this.lastProposedCheckpoint = newProposal;
|
|
675
|
+
// Self-record this slot's outcome on the re-execution tracker. Proposers don't run their
|
|
676
|
+
// own proposals through `handleCheckpointProposal`, so without this call the proposer's
|
|
677
|
+
// sentinel would see no outcome for slots it proposed and would mis-attribute itself as
|
|
678
|
+
// inactive. We pass the locally-computed `archive` (not `newProposal.archive`, which may
|
|
679
|
+
// be intentionally corrupted under test-only flags); from the proposer's local-view
|
|
680
|
+
// perspective the work it just completed is valid by definition.
|
|
681
|
+
this.proposalHandler.recordOwnCheckpointProposalAsValid(checkpointHeader.slotNumber, archive, checkpointNumber);
|
|
534
682
|
return newProposal;
|
|
535
683
|
}
|
|
536
684
|
async broadcastBlockProposal(proposal) {
|
|
@@ -566,27 +714,19 @@ const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT = [
|
|
|
566
714
|
throw new AttestationTimeoutError(0, required, slot);
|
|
567
715
|
}
|
|
568
716
|
await this.collectOwnAttestations(proposal, checkpointNumber);
|
|
569
|
-
const
|
|
717
|
+
const proposalPayloadHash = proposal.getPayloadHash();
|
|
570
718
|
const myAddresses = this.getValidatorAddresses();
|
|
571
719
|
let attestations = [];
|
|
572
720
|
while(true){
|
|
573
|
-
//
|
|
574
|
-
//
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
this.log.warn(`Received attestation for slot ${slot} with mismatched archive from ${attestation.getSender()?.toString()}`, {
|
|
578
|
-
attestationArchive: attestation.archive.toString(),
|
|
579
|
-
proposalArchive: proposal.archive.toString()
|
|
580
|
-
});
|
|
581
|
-
return false;
|
|
582
|
-
}
|
|
583
|
-
return true;
|
|
584
|
-
});
|
|
721
|
+
// The pool already filters by proposal payload hash; if any attestation slips through with a
|
|
722
|
+
// mismatched payload hash, drop it defensively. Equivocations are emitted as separate slash
|
|
723
|
+
// events from libp2p_service.
|
|
724
|
+
const collectedAttestations = await this.p2pClient.getCheckpointAttestationsForSlot(slot, proposalPayloadHash);
|
|
585
725
|
// Log new attestations we collected
|
|
586
726
|
const oldSenders = attestations.map((attestation)=>attestation.getSender());
|
|
587
727
|
for (const collected of collectedAttestations){
|
|
588
728
|
const collectedSender = collected.getSender();
|
|
589
|
-
// Skip attestations with invalid signatures
|
|
729
|
+
// Skip attestations with invalid signatures. Should not happen as we don't add invalid attestations to our pool.
|
|
590
730
|
if (!collectedSender) {
|
|
591
731
|
this.log.warn(`Skipping attestation with invalid signature for slot ${slot}`);
|
|
592
732
|
continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/validator-client",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.b3d3157a",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -64,30 +64,30 @@
|
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/blob-client": "0.0.1-commit.
|
|
68
|
-
"@aztec/blob-lib": "0.0.1-commit.
|
|
69
|
-
"@aztec/constants": "0.0.1-commit.
|
|
70
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
71
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
72
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
73
|
-
"@aztec/node-keystore": "0.0.1-commit.
|
|
74
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
75
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
76
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
77
|
-
"@aztec/prover-client": "0.0.1-commit.
|
|
78
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
79
|
-
"@aztec/slasher": "0.0.1-commit.
|
|
80
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
81
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
82
|
-
"@aztec/validator-ha-signer": "0.0.1-commit.
|
|
67
|
+
"@aztec/blob-client": "0.0.1-commit.b3d3157a",
|
|
68
|
+
"@aztec/blob-lib": "0.0.1-commit.b3d3157a",
|
|
69
|
+
"@aztec/constants": "0.0.1-commit.b3d3157a",
|
|
70
|
+
"@aztec/epoch-cache": "0.0.1-commit.b3d3157a",
|
|
71
|
+
"@aztec/ethereum": "0.0.1-commit.b3d3157a",
|
|
72
|
+
"@aztec/foundation": "0.0.1-commit.b3d3157a",
|
|
73
|
+
"@aztec/node-keystore": "0.0.1-commit.b3d3157a",
|
|
74
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.b3d3157a",
|
|
75
|
+
"@aztec/p2p": "0.0.1-commit.b3d3157a",
|
|
76
|
+
"@aztec/protocol-contracts": "0.0.1-commit.b3d3157a",
|
|
77
|
+
"@aztec/prover-client": "0.0.1-commit.b3d3157a",
|
|
78
|
+
"@aztec/simulator": "0.0.1-commit.b3d3157a",
|
|
79
|
+
"@aztec/slasher": "0.0.1-commit.b3d3157a",
|
|
80
|
+
"@aztec/stdlib": "0.0.1-commit.b3d3157a",
|
|
81
|
+
"@aztec/telemetry-client": "0.0.1-commit.b3d3157a",
|
|
82
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.b3d3157a",
|
|
83
83
|
"koa": "^2.16.1",
|
|
84
84
|
"koa-router": "^13.1.1",
|
|
85
85
|
"tslib": "^2.4.0",
|
|
86
86
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
90
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
89
|
+
"@aztec/archiver": "0.0.1-commit.b3d3157a",
|
|
90
|
+
"@aztec/world-state": "0.0.1-commit.b3d3157a",
|
|
91
91
|
"@electric-sql/pglite": "^0.3.14",
|
|
92
92
|
"@jest/globals": "^30.0.0",
|
|
93
93
|
"@types/jest": "^30.0.0",
|
package/src/config.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
booleanConfigHelper,
|
|
4
4
|
getConfigFromMappings,
|
|
5
5
|
numberConfigHelper,
|
|
6
|
+
optionalNumberConfigHelper,
|
|
6
7
|
secretValueConfigHelper,
|
|
7
8
|
} from '@aztec/foundation/config';
|
|
8
9
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -30,6 +31,12 @@ export const validatorClientConfigMappings: ConfigMappingsType<ValidatorClientCo
|
|
|
30
31
|
.map(address => EthAddress.fromString(address.trim())),
|
|
31
32
|
defaultValue: [],
|
|
32
33
|
},
|
|
34
|
+
l1ChainId: {
|
|
35
|
+
env: 'L1_CHAIN_ID',
|
|
36
|
+
description: 'The chain ID of the ethereum host.',
|
|
37
|
+
parseEnv: (val: string) => +val,
|
|
38
|
+
defaultValue: 31337,
|
|
39
|
+
},
|
|
33
40
|
disableValidator: {
|
|
34
41
|
env: 'VALIDATOR_DISABLED',
|
|
35
42
|
description: 'Do not run the validator',
|
|
@@ -72,25 +79,29 @@ export const validatorClientConfigMappings: ConfigMappingsType<ValidatorClientCo
|
|
|
72
79
|
description: 'Agree to attest to equivocated checkpoint proposals (for testing purposes only)',
|
|
73
80
|
...booleanConfigHelper(false),
|
|
74
81
|
},
|
|
82
|
+
skipProposalSlotValidation: {
|
|
83
|
+
description: 'Accept proposal validation regardless of slot timing (for testing only)',
|
|
84
|
+
...booleanConfigHelper(false),
|
|
85
|
+
},
|
|
75
86
|
validateMaxL2BlockGas: {
|
|
76
87
|
env: 'VALIDATOR_MAX_L2_BLOCK_GAS',
|
|
77
88
|
description: 'Maximum L2 block gas for validation. Proposals exceeding this limit are rejected.',
|
|
78
|
-
|
|
89
|
+
...optionalNumberConfigHelper(),
|
|
79
90
|
},
|
|
80
91
|
validateMaxDABlockGas: {
|
|
81
92
|
env: 'VALIDATOR_MAX_DA_BLOCK_GAS',
|
|
82
93
|
description: 'Maximum DA block gas for validation. Proposals exceeding this limit are rejected.',
|
|
83
|
-
|
|
94
|
+
...optionalNumberConfigHelper(),
|
|
84
95
|
},
|
|
85
96
|
validateMaxTxsPerBlock: {
|
|
86
97
|
env: 'VALIDATOR_MAX_TX_PER_BLOCK',
|
|
87
98
|
description: 'Maximum transactions per block for validation. Proposals exceeding this limit are rejected.',
|
|
88
|
-
|
|
99
|
+
...optionalNumberConfigHelper(),
|
|
89
100
|
},
|
|
90
101
|
validateMaxTxsPerCheckpoint: {
|
|
91
102
|
env: 'VALIDATOR_MAX_TX_PER_CHECKPOINT',
|
|
92
103
|
description: 'Maximum transactions per checkpoint for validation. Proposals exceeding this limit are rejected.',
|
|
93
|
-
|
|
104
|
+
...optionalNumberConfigHelper(),
|
|
94
105
|
},
|
|
95
106
|
...localSignerConfigMappings,
|
|
96
107
|
...validatorHASignerConfigMappings,
|