@aztec/validator-client 3.0.0-canary.a9708bd → 3.0.0-devnet.3
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/dest/block_proposal_handler.d.ts +52 -0
- package/dest/block_proposal_handler.d.ts.map +1 -0
- package/dest/block_proposal_handler.js +286 -0
- package/dest/config.d.ts +3 -19
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +13 -2
- package/dest/duties/validation_service.d.ts +10 -5
- package/dest/duties/validation_service.d.ts.map +1 -1
- package/dest/duties/validation_service.js +19 -6
- package/dest/factory.d.ts +13 -4
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +10 -0
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/key_store/node_keystore_adapter.d.ts.map +1 -1
- package/dest/key_store/node_keystore_adapter.js +2 -4
- package/dest/metrics.d.ts +6 -4
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +22 -11
- package/dest/validator.d.ts +24 -35
- package/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +137 -194
- package/package.json +13 -13
- package/src/block_proposal_handler.ts +343 -0
- package/src/config.ts +24 -25
- package/src/duties/validation_service.ts +30 -9
- package/src/factory.ts +34 -4
- package/src/index.ts +1 -0
- package/src/key_store/node_keystore_adapter.ts +2 -3
- package/src/metrics.ts +32 -13
- package/src/validator.ts +194 -276
package/dest/metrics.d.ts
CHANGED
|
@@ -2,15 +2,17 @@ import type { BlockProposal } from '@aztec/stdlib/p2p';
|
|
|
2
2
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
3
3
|
export declare class ValidatorMetrics {
|
|
4
4
|
private failedReexecutionCounter;
|
|
5
|
-
private
|
|
6
|
-
private
|
|
5
|
+
private successfulAttestationsCount;
|
|
6
|
+
private failedAttestationsBadProposalCount;
|
|
7
|
+
private failedAttestationsNodeIssueCount;
|
|
7
8
|
private reexMana;
|
|
8
9
|
private reexTx;
|
|
9
10
|
private reexDuration;
|
|
10
11
|
constructor(telemetryClient: TelemetryClient);
|
|
11
12
|
recordReex(time: number, txs: number, mManaTotal: number): void;
|
|
12
13
|
recordFailedReexecution(proposal: BlockProposal): void;
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
incSuccessfulAttestations(num: number): void;
|
|
15
|
+
incFailedAttestationsBadProposal(num: number, reason: string): void;
|
|
16
|
+
incFailedAttestationsNodeIssue(num: number, reason: string): void;
|
|
15
17
|
}
|
|
16
18
|
//# sourceMappingURL=metrics.d.ts.map
|
package/dest/metrics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAIL,KAAK,eAAe,EAGrB,MAAM,yBAAyB,CAAC;AAEjC,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,wBAAwB,CAAgB;IAChD,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAIL,KAAK,eAAe,EAGrB,MAAM,yBAAyB,CAAC;AAEjC,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,wBAAwB,CAAgB;IAChD,OAAO,CAAC,2BAA2B,CAAgB;IACnD,OAAO,CAAC,kCAAkC,CAAgB;IAC1D,OAAO,CAAC,gCAAgC,CAAgB;IAExD,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,YAAY,CAAY;gBAEpB,eAAe,EAAE,eAAe;IAiDrC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAMxD,uBAAuB,CAAC,QAAQ,EAAE,aAAa;IAQ/C,yBAAyB,CAAC,GAAG,EAAE,MAAM;IAIrC,gCAAgC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAM5D,8BAA8B,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAKlE"}
|
package/dest/metrics.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Attributes, Metrics, ValueType } from '@aztec/telemetry-client';
|
|
2
2
|
export class ValidatorMetrics {
|
|
3
3
|
failedReexecutionCounter;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
successfulAttestationsCount;
|
|
5
|
+
failedAttestationsBadProposalCount;
|
|
6
|
+
failedAttestationsNodeIssueCount;
|
|
6
7
|
reexMana;
|
|
7
8
|
reexTx;
|
|
8
9
|
reexDuration;
|
|
@@ -13,12 +14,16 @@ export class ValidatorMetrics {
|
|
|
13
14
|
unit: 'count',
|
|
14
15
|
valueType: ValueType.INT
|
|
15
16
|
});
|
|
16
|
-
this.
|
|
17
|
-
description: 'The number of attestations',
|
|
17
|
+
this.successfulAttestationsCount = meter.createUpDownCounter(Metrics.VALIDATOR_ATTESTATION_SUCCESS_COUNT, {
|
|
18
|
+
description: 'The number of successful attestations',
|
|
18
19
|
valueType: ValueType.INT
|
|
19
20
|
});
|
|
20
|
-
this.
|
|
21
|
-
description: 'The number of failed attestations',
|
|
21
|
+
this.failedAttestationsBadProposalCount = meter.createUpDownCounter(Metrics.VALIDATOR_ATTESTATION_FAILED_BAD_PROPOSAL_COUNT, {
|
|
22
|
+
description: 'The number of failed attestations due to invalid block proposals',
|
|
23
|
+
valueType: ValueType.INT
|
|
24
|
+
});
|
|
25
|
+
this.failedAttestationsNodeIssueCount = meter.createUpDownCounter(Metrics.VALIDATOR_ATTESTATION_FAILED_NODE_ISSUE_COUNT, {
|
|
26
|
+
description: 'The number of failed attestations due to node issues (timeout, missing data, etc.)',
|
|
22
27
|
valueType: ValueType.INT
|
|
23
28
|
});
|
|
24
29
|
this.reexMana = meter.createHistogram(Metrics.VALIDATOR_RE_EXECUTION_MANA, {
|
|
@@ -43,16 +48,22 @@ export class ValidatorMetrics {
|
|
|
43
48
|
this.reexMana.record(mManaTotal);
|
|
44
49
|
}
|
|
45
50
|
recordFailedReexecution(proposal) {
|
|
51
|
+
const proposer = proposal.getSender();
|
|
46
52
|
this.failedReexecutionCounter.add(1, {
|
|
47
53
|
[Attributes.STATUS]: 'failed',
|
|
48
|
-
[Attributes.BLOCK_PROPOSER]:
|
|
54
|
+
[Attributes.BLOCK_PROPOSER]: proposer?.toString() ?? 'unknown'
|
|
49
55
|
});
|
|
50
56
|
}
|
|
51
|
-
|
|
52
|
-
this.
|
|
57
|
+
incSuccessfulAttestations(num) {
|
|
58
|
+
this.successfulAttestationsCount.add(num);
|
|
59
|
+
}
|
|
60
|
+
incFailedAttestationsBadProposal(num, reason) {
|
|
61
|
+
this.failedAttestationsBadProposalCount.add(num, {
|
|
62
|
+
[Attributes.ERROR_TYPE]: reason
|
|
63
|
+
});
|
|
53
64
|
}
|
|
54
|
-
|
|
55
|
-
this.
|
|
65
|
+
incFailedAttestationsNodeIssue(num, reason) {
|
|
66
|
+
this.failedAttestationsNodeIssueCount.add(num, {
|
|
56
67
|
[Attributes.ERROR_TYPE]: reason
|
|
57
68
|
});
|
|
58
69
|
}
|
package/dest/validator.d.ts
CHANGED
|
@@ -1,78 +1,67 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
2
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import type { Signature } from '@aztec/foundation/eth-signature';
|
|
3
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
|
+
import { type Logger } from '@aztec/foundation/log';
|
|
4
6
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
5
7
|
import type { KeystoreManager } from '@aztec/node-keystore';
|
|
6
|
-
import type { P2P, PeerId } from '@aztec/p2p';
|
|
7
|
-
import {
|
|
8
|
-
import { type SlasherConfig, type Watcher, type WatcherEmitter } from '@aztec/slasher';
|
|
8
|
+
import type { P2P, PeerId, TxProvider } from '@aztec/p2p';
|
|
9
|
+
import { type Watcher, type WatcherEmitter } from '@aztec/slasher';
|
|
9
10
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
10
|
-
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
11
|
-
import type { IFullNodeBlockBuilder,
|
|
11
|
+
import type { CommitteeAttestationsAndSigners, L2BlockSource } from '@aztec/stdlib/block';
|
|
12
|
+
import type { IFullNodeBlockBuilder, Validator, ValidatorClientFullConfig } from '@aztec/stdlib/interfaces/server';
|
|
12
13
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
13
14
|
import type { BlockAttestation, BlockProposal, BlockProposalOptions } from '@aztec/stdlib/p2p';
|
|
14
|
-
import
|
|
15
|
+
import type { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
16
|
+
import type { StateReference, Tx } from '@aztec/stdlib/tx';
|
|
15
17
|
import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
|
|
16
18
|
import type { TypedDataDefinition } from 'viem';
|
|
17
|
-
import
|
|
19
|
+
import { BlockProposalHandler } from './block_proposal_handler.js';
|
|
18
20
|
import { NodeKeystoreAdapter } from './key_store/node_keystore_adapter.js';
|
|
19
|
-
export interface Validator {
|
|
20
|
-
start(): Promise<void>;
|
|
21
|
-
registerBlockProposalHandler(): void;
|
|
22
|
-
createBlockProposal(blockNumber: number, header: ProposedBlockHeader, archive: Fr, stateReference: StateReference, txs: Tx[], proposerAddress: EthAddress | undefined, options: BlockProposalOptions): Promise<BlockProposal | undefined>;
|
|
23
|
-
attestToProposal(proposal: BlockProposal, sender: PeerId): Promise<BlockAttestation[] | undefined>;
|
|
24
|
-
broadcastBlockProposal(proposal: BlockProposal): Promise<void>;
|
|
25
|
-
collectAttestations(proposal: BlockProposal, required: number, deadline: Date): Promise<BlockAttestation[]>;
|
|
26
|
-
}
|
|
27
21
|
declare const ValidatorClient_base: new () => WatcherEmitter;
|
|
28
22
|
/**
|
|
29
23
|
* Validator Client
|
|
30
24
|
*/
|
|
31
25
|
export declare class ValidatorClient extends ValidatorClient_base implements Validator, Watcher {
|
|
32
|
-
private blockBuilder;
|
|
33
26
|
private keyStore;
|
|
34
27
|
private epochCache;
|
|
35
28
|
private p2pClient;
|
|
36
|
-
private
|
|
37
|
-
private l1ToL2MessageSource;
|
|
38
|
-
private txProvider;
|
|
29
|
+
private blockProposalHandler;
|
|
39
30
|
private config;
|
|
40
31
|
private dateProvider;
|
|
41
32
|
private log;
|
|
42
33
|
readonly tracer: Tracer;
|
|
43
34
|
private validationService;
|
|
44
35
|
private metrics;
|
|
36
|
+
private hasRegisteredHandlers;
|
|
45
37
|
private previousProposal?;
|
|
46
|
-
private myAddresses;
|
|
47
38
|
private lastEpochForCommitteeUpdateLoop;
|
|
48
39
|
private epochCacheUpdateLoop;
|
|
49
|
-
private blockProposalValidator;
|
|
50
40
|
private proposersOfInvalidBlocks;
|
|
51
|
-
protected constructor(
|
|
52
|
-
static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager): void;
|
|
41
|
+
protected constructor(keyStore: NodeKeystoreAdapter, epochCache: EpochCache, p2pClient: P2P, blockProposalHandler: BlockProposalHandler, config: ValidatorClientFullConfig, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: Logger);
|
|
42
|
+
static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager, logger?: Logger): void;
|
|
53
43
|
private handleEpochCommitteeUpdate;
|
|
54
|
-
static new(config:
|
|
44
|
+
static new(config: ValidatorClientFullConfig, blockBuilder: IFullNodeBlockBuilder, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, keyStoreManager: KeystoreManager, dateProvider?: DateProvider, telemetry?: TelemetryClient): ValidatorClient;
|
|
55
45
|
getValidatorAddresses(): EthAddress[];
|
|
56
|
-
|
|
46
|
+
getBlockProposalHandler(): BlockProposalHandler;
|
|
47
|
+
reExecuteTransactions(proposal: BlockProposal, blockNumber: number, txs: any[], l1ToL2Messages: Fr[]): Promise<any>;
|
|
48
|
+
signWithAddress(addr: EthAddress, msg: TypedDataDefinition): Promise<Signature>;
|
|
57
49
|
getCoinbaseForAttestor(attestor: EthAddress): EthAddress;
|
|
58
50
|
getFeeRecipientForAttestor(attestor: EthAddress): AztecAddress;
|
|
59
|
-
|
|
51
|
+
getConfig(): ValidatorClientFullConfig;
|
|
52
|
+
updateConfig(config: Partial<ValidatorClientFullConfig>): void;
|
|
60
53
|
start(): Promise<void>;
|
|
61
54
|
stop(): Promise<void>;
|
|
62
|
-
|
|
55
|
+
/** Register handlers on the p2p client */
|
|
56
|
+
registerHandlers(): Promise<void>;
|
|
63
57
|
attestToProposal(proposal: BlockProposal, proposalSender: PeerId): Promise<BlockAttestation[] | undefined>;
|
|
64
|
-
private getReexecutionDeadline;
|
|
65
|
-
/**
|
|
66
|
-
* Re-execute the transactions in the proposal and check that the state updates match the header state
|
|
67
|
-
* @param proposal - The proposal to re-execute
|
|
68
|
-
*/
|
|
69
|
-
reExecuteTransactions(proposal: BlockProposal, txs: Tx[], l1ToL2Messages: Fr[]): Promise<void>;
|
|
70
58
|
private slashInvalidBlock;
|
|
71
|
-
createBlockProposal(blockNumber: number, header:
|
|
59
|
+
createBlockProposal(blockNumber: number, header: CheckpointHeader, archive: Fr, stateReference: StateReference, txs: Tx[], proposerAddress: EthAddress | undefined, options: BlockProposalOptions): Promise<BlockProposal | undefined>;
|
|
72
60
|
broadcastBlockProposal(proposal: BlockProposal): Promise<void>;
|
|
61
|
+
signAttestationsAndSigners(attestationsAndSigners: CommitteeAttestationsAndSigners, proposer: EthAddress): Promise<Signature>;
|
|
73
62
|
collectOwnAttestations(proposal: BlockProposal): Promise<BlockAttestation[]>;
|
|
74
63
|
collectAttestations(proposal: BlockProposal, required: number, deadline: Date): Promise<BlockAttestation[]>;
|
|
75
|
-
private
|
|
64
|
+
private createBlockAttestationsFromProposal;
|
|
76
65
|
private handleAuthRequest;
|
|
77
66
|
}
|
|
78
67
|
export {};
|
package/dest/validator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
|