@aztec/validator-client 3.0.0-nightly.20250906 → 3.0.0-nightly.20250910
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/duties/validation_service.d.ts +3 -0
- package/dest/duties/validation_service.d.ts.map +1 -1
- package/dest/duties/validation_service.js +4 -0
- package/dest/validator.d.ts +7 -4
- package/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +9 -3
- package/package.json +11 -11
- package/src/duties/validation_service.ts +11 -0
- package/src/validator.ts +18 -5
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import type { Signature } from '@aztec/foundation/eth-signature';
|
|
2
3
|
import type { Fr } from '@aztec/foundation/fields';
|
|
4
|
+
import type { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
3
5
|
import { BlockAttestation, BlockProposal, type BlockProposalOptions } from '@aztec/stdlib/p2p';
|
|
4
6
|
import type { ProposedBlockHeader, StateReference, Tx } from '@aztec/stdlib/tx';
|
|
5
7
|
import type { ValidatorKeyStore } from '../key_store/interface.js';
|
|
@@ -28,5 +30,6 @@ export declare class ValidationService {
|
|
|
28
30
|
* @returns attestations
|
|
29
31
|
*/
|
|
30
32
|
attestToProposal(proposal: BlockProposal, attestors: EthAddress[]): Promise<BlockAttestation[]>;
|
|
33
|
+
signAttestationsAndSigners(attestationsAndSigners: CommitteeAttestationsAndSigners, proposer: EthAddress): Promise<Signature>;
|
|
31
34
|
}
|
|
32
35
|
//# sourceMappingURL=validation_service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation_service.d.ts","sourceRoot":"","sources":["../../src/duties/validation_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"validation_service.d.ts","sourceRoot":"","sources":["../../src/duties/validation_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,oBAAoB,EAG1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,iBAAiB;IAE/C;;;;;;;;;OASG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,EAAE,EACX,cAAc,EAAE,cAAc,EAC9B,GAAG,EAAE,EAAE,EAAE,EACT,uBAAuB,EAAE,UAAU,GAAG,SAAS,EAC/C,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC;IAqBzB;;;;;;;;;OASG;IACG,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAW/F,0BAA0B,CAC9B,sBAAsB,EAAE,+BAA+B,EACvD,QAAQ,EAAE,UAAU,GACnB,OAAO,CAAC,SAAS,CAAC;CAMtB"}
|
|
@@ -43,4 +43,8 @@ export class ValidationService {
|
|
|
43
43
|
//await this.keyStore.signMessage(buf);
|
|
44
44
|
return signatures.map((sig)=>new BlockAttestation(proposal.blockNumber, proposal.payload, sig));
|
|
45
45
|
}
|
|
46
|
+
async signAttestationsAndSigners(attestationsAndSigners, proposer) {
|
|
47
|
+
const buf = Buffer32.fromBuffer(keccak256(attestationsAndSigners.getPayloadToSign(SignatureDomainSeparator.attestationsAndSigners)));
|
|
48
|
+
return await this.keyStore.signMessageWithAddress(proposer, buf);
|
|
49
|
+
}
|
|
46
50
|
}
|
package/dest/validator.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
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
8
|
import type { P2P, PeerId } from '@aztec/p2p';
|
|
7
9
|
import { TxProvider } from '@aztec/p2p';
|
|
8
10
|
import { type SlasherConfig, type Watcher, type WatcherEmitter } from '@aztec/slasher';
|
|
9
11
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
10
|
-
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
12
|
+
import type { CommitteeAttestationsAndSigners, L2BlockSource } from '@aztec/stdlib/block';
|
|
11
13
|
import type { IFullNodeBlockBuilder, Validator, ValidatorClientFullConfig } from '@aztec/stdlib/interfaces/server';
|
|
12
14
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
13
15
|
import type { BlockAttestation, BlockProposal, BlockProposalOptions } from '@aztec/stdlib/p2p';
|
|
@@ -39,12 +41,12 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
|
|
|
39
41
|
private epochCacheUpdateLoop;
|
|
40
42
|
private blockProposalValidator;
|
|
41
43
|
private proposersOfInvalidBlocks;
|
|
42
|
-
protected constructor(blockBuilder: IFullNodeBlockBuilder, keyStore: NodeKeystoreAdapter, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, config: ValidatorClientFullConfig, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?:
|
|
43
|
-
static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager): void;
|
|
44
|
+
protected constructor(blockBuilder: IFullNodeBlockBuilder, keyStore: NodeKeystoreAdapter, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, config: ValidatorClientFullConfig, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: Logger);
|
|
45
|
+
static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager, logger?: Logger): void;
|
|
44
46
|
private handleEpochCommitteeUpdate;
|
|
45
47
|
static new(config: ValidatorClientConfig & Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'>, blockBuilder: IFullNodeBlockBuilder, epochCache: EpochCache, p2pClient: P2P, blockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, keyStoreManager: KeystoreManager, dateProvider?: DateProvider, telemetry?: TelemetryClient): ValidatorClient;
|
|
46
48
|
getValidatorAddresses(): EthAddress[];
|
|
47
|
-
signWithAddress(addr: EthAddress, msg: TypedDataDefinition): Promise<
|
|
49
|
+
signWithAddress(addr: EthAddress, msg: TypedDataDefinition): Promise<Signature>;
|
|
48
50
|
getCoinbaseForAttestor(attestor: EthAddress): EthAddress;
|
|
49
51
|
getFeeRecipientForAttestor(attestor: EthAddress): AztecAddress;
|
|
50
52
|
getConfig(): ValidatorClientFullConfig;
|
|
@@ -62,6 +64,7 @@ export declare class ValidatorClient extends ValidatorClient_base implements Val
|
|
|
62
64
|
private slashInvalidBlock;
|
|
63
65
|
createBlockProposal(blockNumber: number, header: ProposedBlockHeader, archive: Fr, stateReference: StateReference, txs: Tx[], proposerAddress: EthAddress | undefined, options: BlockProposalOptions): Promise<BlockProposal | undefined>;
|
|
64
66
|
broadcastBlockProposal(proposal: BlockProposal): Promise<void>;
|
|
67
|
+
signAttestationsAndSigners(attestationsAndSigners: CommitteeAttestationsAndSigners, proposer: EthAddress): Promise<Signature>;
|
|
65
68
|
collectOwnAttestations(proposal: BlockProposal): Promise<BlockAttestation[]>;
|
|
66
69
|
collectAttestations(proposal: BlockProposal, required: number, deadline: Date): Promise<BlockAttestation[]>;
|
|
67
70
|
private doAttestToProposal;
|
package/dest/validator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
|
package/dest/validator.js
CHANGED
|
@@ -53,15 +53,17 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
|
53
53
|
const myAddresses = this.getValidatorAddresses();
|
|
54
54
|
this.log.verbose(`Initialized validator with addresses: ${myAddresses.map((a)=>a.toString()).join(', ')}`);
|
|
55
55
|
}
|
|
56
|
-
static validateKeyStoreConfiguration(keyStoreManager) {
|
|
56
|
+
static validateKeyStoreConfiguration(keyStoreManager, logger) {
|
|
57
57
|
const validatorKeyStore = NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager);
|
|
58
58
|
const validatorAddresses = validatorKeyStore.getAddresses();
|
|
59
59
|
// Verify that we can retrieve all required data from the key store
|
|
60
60
|
for (const address of validatorAddresses){
|
|
61
61
|
// Functions throw if required data is not available
|
|
62
|
+
let coinbase;
|
|
63
|
+
let feeRecipient;
|
|
62
64
|
try {
|
|
63
|
-
validatorKeyStore.getCoinbaseAddress(address);
|
|
64
|
-
validatorKeyStore.getFeeRecipient(address);
|
|
65
|
+
coinbase = validatorKeyStore.getCoinbaseAddress(address);
|
|
66
|
+
feeRecipient = validatorKeyStore.getFeeRecipient(address);
|
|
65
67
|
} catch (error) {
|
|
66
68
|
throw new Error(`Failed to retrieve required data for validator address ${address}, error: ${error}`);
|
|
67
69
|
}
|
|
@@ -69,6 +71,7 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
|
69
71
|
if (!publisherAddresses.length) {
|
|
70
72
|
throw new Error(`No publisher addresses found for validator address ${address}`);
|
|
71
73
|
}
|
|
74
|
+
logger?.debug(`Validator ${address.toString()} configured with coinbase ${coinbase.toString()}, feeRecipient ${feeRecipient.toString()} and publishers ${publisherAddresses.map((x)=>x.toString()).join()}`);
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
async handleEpochCommitteeUpdate() {
|
|
@@ -340,6 +343,9 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
|
340
343
|
async broadcastBlockProposal(proposal) {
|
|
341
344
|
await this.p2pClient.broadcastProposal(proposal);
|
|
342
345
|
}
|
|
346
|
+
async signAttestationsAndSigners(attestationsAndSigners, proposer) {
|
|
347
|
+
return await this.validationService.signAttestationsAndSigners(attestationsAndSigners, proposer);
|
|
348
|
+
}
|
|
343
349
|
async collectOwnAttestations(proposal) {
|
|
344
350
|
const slot = proposal.payload.header.slotNumber.toBigInt();
|
|
345
351
|
const inCommittee = await this.epochCache.filterInCommittee(slot, this.getValidatorAddresses());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/validator-client",
|
|
3
|
-
"version": "3.0.0-nightly.
|
|
3
|
+
"version": "3.0.0-nightly.20250910",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -64,16 +64,16 @@
|
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/constants": "3.0.0-nightly.
|
|
68
|
-
"@aztec/epoch-cache": "3.0.0-nightly.
|
|
69
|
-
"@aztec/ethereum": "3.0.0-nightly.
|
|
70
|
-
"@aztec/foundation": "3.0.0-nightly.
|
|
71
|
-
"@aztec/node-keystore": "3.0.0-nightly.
|
|
72
|
-
"@aztec/p2p": "3.0.0-nightly.
|
|
73
|
-
"@aztec/prover-client": "3.0.0-nightly.
|
|
74
|
-
"@aztec/slasher": "3.0.0-nightly.
|
|
75
|
-
"@aztec/stdlib": "3.0.0-nightly.
|
|
76
|
-
"@aztec/telemetry-client": "3.0.0-nightly.
|
|
67
|
+
"@aztec/constants": "3.0.0-nightly.20250910",
|
|
68
|
+
"@aztec/epoch-cache": "3.0.0-nightly.20250910",
|
|
69
|
+
"@aztec/ethereum": "3.0.0-nightly.20250910",
|
|
70
|
+
"@aztec/foundation": "3.0.0-nightly.20250910",
|
|
71
|
+
"@aztec/node-keystore": "3.0.0-nightly.20250910",
|
|
72
|
+
"@aztec/p2p": "3.0.0-nightly.20250910",
|
|
73
|
+
"@aztec/prover-client": "3.0.0-nightly.20250910",
|
|
74
|
+
"@aztec/slasher": "3.0.0-nightly.20250910",
|
|
75
|
+
"@aztec/stdlib": "3.0.0-nightly.20250910",
|
|
76
|
+
"@aztec/telemetry-client": "3.0.0-nightly.20250910",
|
|
77
77
|
"koa": "^2.16.1",
|
|
78
78
|
"koa-router": "^12.0.0",
|
|
79
79
|
"tslib": "^2.4.0",
|
|
@@ -3,6 +3,7 @@ import { keccak256 } from '@aztec/foundation/crypto';
|
|
|
3
3
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import type { Signature } from '@aztec/foundation/eth-signature';
|
|
5
5
|
import type { Fr } from '@aztec/foundation/fields';
|
|
6
|
+
import type { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
6
7
|
import {
|
|
7
8
|
BlockAttestation,
|
|
8
9
|
BlockProposal,
|
|
@@ -76,4 +77,14 @@ export class ValidationService {
|
|
|
76
77
|
//await this.keyStore.signMessage(buf);
|
|
77
78
|
return signatures.map(sig => new BlockAttestation(proposal.blockNumber, proposal.payload, sig));
|
|
78
79
|
}
|
|
80
|
+
|
|
81
|
+
async signAttestationsAndSigners(
|
|
82
|
+
attestationsAndSigners: CommitteeAttestationsAndSigners,
|
|
83
|
+
proposer: EthAddress,
|
|
84
|
+
): Promise<Signature> {
|
|
85
|
+
const buf = Buffer32.fromBuffer(
|
|
86
|
+
keccak256(attestationsAndSigners.getPayloadToSign(SignatureDomainSeparator.attestationsAndSigners)),
|
|
87
|
+
);
|
|
88
|
+
return await this.keyStore.signMessageWithAddress(proposer, buf);
|
|
89
|
+
}
|
|
79
90
|
}
|
package/src/validator.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
2
2
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
3
3
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
+
import type { Signature } from '@aztec/foundation/eth-signature';
|
|
4
5
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
6
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
6
7
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
7
8
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
8
9
|
import { sleep } from '@aztec/foundation/sleep';
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
type WatcherEmitter,
|
|
21
22
|
} from '@aztec/slasher';
|
|
22
23
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
23
|
-
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
24
|
+
import type { CommitteeAttestationsAndSigners, L2BlockSource } from '@aztec/stdlib/block';
|
|
24
25
|
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
25
26
|
import type { IFullNodeBlockBuilder, Validator, ValidatorClientFullConfig } from '@aztec/stdlib/interfaces/server';
|
|
26
27
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
@@ -93,15 +94,17 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
93
94
|
this.log.verbose(`Initialized validator with addresses: ${myAddresses.map(a => a.toString()).join(', ')}`);
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
public static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager) {
|
|
97
|
+
public static validateKeyStoreConfiguration(keyStoreManager: KeystoreManager, logger?: Logger) {
|
|
97
98
|
const validatorKeyStore = NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager);
|
|
98
99
|
const validatorAddresses = validatorKeyStore.getAddresses();
|
|
99
100
|
// Verify that we can retrieve all required data from the key store
|
|
100
101
|
for (const address of validatorAddresses) {
|
|
101
102
|
// Functions throw if required data is not available
|
|
103
|
+
let coinbase: EthAddress;
|
|
104
|
+
let feeRecipient: AztecAddress;
|
|
102
105
|
try {
|
|
103
|
-
validatorKeyStore.getCoinbaseAddress(address);
|
|
104
|
-
validatorKeyStore.getFeeRecipient(address);
|
|
106
|
+
coinbase = validatorKeyStore.getCoinbaseAddress(address);
|
|
107
|
+
feeRecipient = validatorKeyStore.getFeeRecipient(address);
|
|
105
108
|
} catch (error) {
|
|
106
109
|
throw new Error(`Failed to retrieve required data for validator address ${address}, error: ${error}`);
|
|
107
110
|
}
|
|
@@ -110,6 +113,9 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
110
113
|
if (!publisherAddresses.length) {
|
|
111
114
|
throw new Error(`No publisher addresses found for validator address ${address}`);
|
|
112
115
|
}
|
|
116
|
+
logger?.debug(
|
|
117
|
+
`Validator ${address.toString()} configured with coinbase ${coinbase.toString()}, feeRecipient ${feeRecipient.toString()} and publishers ${publisherAddresses.map(x => x.toString()).join()}`,
|
|
118
|
+
);
|
|
113
119
|
}
|
|
114
120
|
}
|
|
115
121
|
|
|
@@ -490,6 +496,13 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
490
496
|
await this.p2pClient.broadcastProposal(proposal);
|
|
491
497
|
}
|
|
492
498
|
|
|
499
|
+
async signAttestationsAndSigners(
|
|
500
|
+
attestationsAndSigners: CommitteeAttestationsAndSigners,
|
|
501
|
+
proposer: EthAddress,
|
|
502
|
+
): Promise<Signature> {
|
|
503
|
+
return await this.validationService.signAttestationsAndSigners(attestationsAndSigners, proposer);
|
|
504
|
+
}
|
|
505
|
+
|
|
493
506
|
async collectOwnAttestations(proposal: BlockProposal): Promise<BlockAttestation[]> {
|
|
494
507
|
const slot = proposal.payload.header.slotNumber.toBigInt();
|
|
495
508
|
const inCommittee = await this.epochCache.filterInCommittee(slot, this.getValidatorAddresses());
|