@aztec/aztec-node 2.0.0-nightly.20250826 → 2.0.0-nightly.20250828
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/aztec-node/config.d.ts +4 -2
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +66 -0
- package/dest/aztec-node/server.d.ts +1 -1
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +36 -14
- package/dest/sentinel/sentinel.d.ts +1 -2
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +6 -27
- package/package.json +24 -23
- package/src/aztec-node/config.ts +108 -1
- package/src/aztec-node/server.ts +38 -19
- package/src/sentinel/sentinel.ts +4 -31
|
@@ -2,10 +2,11 @@ import { type ArchiverConfig } from '@aztec/archiver/config';
|
|
|
2
2
|
import { type GenesisStateConfig, type L1ContractAddresses } from '@aztec/ethereum';
|
|
3
3
|
import { type ConfigMappingsType } from '@aztec/foundation/config';
|
|
4
4
|
import { type DataStoreConfig } from '@aztec/kv-store/config';
|
|
5
|
+
import { type KeyStore, type KeyStoreConfig } from '@aztec/node-keystore';
|
|
5
6
|
import { type SharedNodeConfig } from '@aztec/node-lib/config';
|
|
6
7
|
import { type P2PConfig } from '@aztec/p2p/config';
|
|
7
8
|
import { type ProverClientUserConfig } from '@aztec/prover-client/config';
|
|
8
|
-
import { type SequencerClientConfig, sequencerClientConfigMappings } from '@aztec/sequencer-client/config';
|
|
9
|
+
import { type SequencerClientConfig, type TxSenderConfig, sequencerClientConfigMappings } from '@aztec/sequencer-client/config';
|
|
9
10
|
import { type NodeRPCConfig } from '@aztec/stdlib/config';
|
|
10
11
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
11
12
|
import { type ValidatorClientConfig } from '@aztec/validator-client/config';
|
|
@@ -15,7 +16,7 @@ export { sequencerClientConfigMappings, type SequencerClientConfig };
|
|
|
15
16
|
/**
|
|
16
17
|
* The configuration the aztec node.
|
|
17
18
|
*/
|
|
18
|
-
export type AztecNodeConfig = ArchiverConfig & SequencerClientConfig & ValidatorClientConfig & ProverClientUserConfig & WorldStateConfig & Pick<ProverClientUserConfig, 'bbBinaryPath' | 'bbWorkingDirectory' | 'realProofs'> & P2PConfig & DataStoreConfig & SentinelConfig & SharedNodeConfig & GenesisStateConfig & NodeRPCConfig & SlasherConfig & {
|
|
19
|
+
export type AztecNodeConfig = ArchiverConfig & SequencerClientConfig & ValidatorClientConfig & ProverClientUserConfig & WorldStateConfig & Pick<ProverClientUserConfig, 'bbBinaryPath' | 'bbWorkingDirectory' | 'realProofs'> & P2PConfig & DataStoreConfig & KeyStoreConfig & SentinelConfig & SharedNodeConfig & GenesisStateConfig & NodeRPCConfig & SlasherConfig & {
|
|
19
20
|
/** L1 contracts addresses */
|
|
20
21
|
l1Contracts: L1ContractAddresses;
|
|
21
22
|
/** Whether the validator is disabled for this node */
|
|
@@ -27,4 +28,5 @@ export declare const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig
|
|
|
27
28
|
* @returns A valid aztec node config.
|
|
28
29
|
*/
|
|
29
30
|
export declare function getConfigEnvVars(): AztecNodeConfig;
|
|
31
|
+
export declare function createKeyStoreForValidator(config: TxSenderConfig & SequencerClientConfig & SharedNodeConfig): KeyStore | undefined;
|
|
30
32
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/aztec-node/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,wBAAwB,CAAC;AACrF,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EAGzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,kBAAkB,EAA8C,MAAM,0BAA0B,CAAC;AAC/G,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,KAAK,sBAAsB,EAA8B,MAAM,6BAA6B,CAAC;AACtG,OAAO,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/aztec-node/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,wBAAwB,CAAC;AACrF,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EAGzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,kBAAkB,EAA8C,MAAM,0BAA0B,CAAC;AAC/G,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAML,KAAK,QAAQ,EACb,KAAK,cAAc,EAGpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,KAAK,sBAAsB,EAA8B,MAAM,6BAA6B,CAAC;AACtG,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,6BAA6B,EAC9B,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,KAAK,aAAa,EAAyB,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,KAAK,qBAAqB,EAAiC,MAAM,gCAAgC,CAAC;AAC3G,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,2BAA2B,CAAC;AAI5F,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,uBAAuB,CAAC;AAEpF,OAAO,EAAE,6BAA6B,EAAE,KAAK,qBAAqB,EAAE,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,GAC1C,qBAAqB,GACrB,qBAAqB,GACrB,sBAAsB,GACtB,gBAAgB,GAChB,IAAI,CAAC,sBAAsB,EAAE,cAAc,GAAG,oBAAoB,GAAG,YAAY,CAAC,GAClF,SAAS,GACT,eAAe,GACf,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,kBAAkB,GAClB,aAAa,GACb,aAAa,GAAG;IACd,6BAA6B;IAC7B,WAAW,EAAE,mBAAmB,CAAC;IACjC,sDAAsD;IACtD,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEJ,eAAO,MAAM,uBAAuB,EAAE,kBAAkB,CAAC,eAAe,CAuBvE,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,eAAe,CAElD;AAiFD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,cAAc,GAAG,qBAAqB,GAAG,gBAAgB,wBAM3G"}
|
|
@@ -2,18 +2,22 @@ import { archiverConfigMappings } from '@aztec/archiver/config';
|
|
|
2
2
|
import { genesisStateConfigMappings, l1ContractAddressesMapping } from '@aztec/ethereum';
|
|
3
3
|
import { booleanConfigHelper, getConfigFromMappings } from '@aztec/foundation/config';
|
|
4
4
|
import { dataConfigMappings } from '@aztec/kv-store/config';
|
|
5
|
+
import { keyStoreConfigMappings } from '@aztec/node-keystore';
|
|
5
6
|
import { sharedNodeConfigMappings } from '@aztec/node-lib/config';
|
|
6
7
|
import { p2pConfigMappings } from '@aztec/p2p/config';
|
|
7
8
|
import { proverClientConfigMappings } from '@aztec/prover-client/config';
|
|
8
9
|
import { sequencerClientConfigMappings } from '@aztec/sequencer-client/config';
|
|
9
10
|
import { slasherConfigMappings } from '@aztec/slasher';
|
|
11
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
10
12
|
import { nodeRpcConfigMappings } from '@aztec/stdlib/config';
|
|
11
13
|
import { validatorClientConfigMappings } from '@aztec/validator-client/config';
|
|
12
14
|
import { worldStateConfigMappings } from '@aztec/world-state/config';
|
|
15
|
+
import { privateKeyToAddress } from 'viem/accounts';
|
|
13
16
|
import { sentinelConfigMappings } from '../sentinel/config.js';
|
|
14
17
|
export { sequencerClientConfigMappings };
|
|
15
18
|
export const aztecNodeConfigMappings = {
|
|
16
19
|
...dataConfigMappings,
|
|
20
|
+
...keyStoreConfigMappings,
|
|
17
21
|
...archiverConfigMappings,
|
|
18
22
|
...sequencerClientConfigMappings,
|
|
19
23
|
...validatorClientConfigMappings,
|
|
@@ -41,3 +45,65 @@ export const aztecNodeConfigMappings = {
|
|
|
41
45
|
*/ export function getConfigEnvVars() {
|
|
42
46
|
return getConfigFromMappings(aztecNodeConfigMappings);
|
|
43
47
|
}
|
|
48
|
+
function createKeyStoreFromWeb3Signer(config) {
|
|
49
|
+
const validatorKeyStores = [];
|
|
50
|
+
if (config.web3SignerUrl === undefined || config.web3SignerUrl.length === 0 || config.validatorAddresses === undefined || config.validatorAddresses.length === 0) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
const coinbase = config.coinbase ? config.coinbase.toString() : config.validatorAddresses[0].toString();
|
|
54
|
+
const feeRecipient = config.feeRecipient ? config.feeRecipient.toString() : AztecAddress.ZERO.toString();
|
|
55
|
+
const publisherAddresses = config.publisherAddresses && config.publisherAddresses.length > 0 ? config.publisherAddresses.map((k)=>k.toChecksumString()) : [];
|
|
56
|
+
const attestors = config.validatorAddresses.map((k)=>k.toChecksumString());
|
|
57
|
+
validatorKeyStores.push({
|
|
58
|
+
attester: attestors,
|
|
59
|
+
feeRecipient: feeRecipient,
|
|
60
|
+
coinbase: coinbase,
|
|
61
|
+
remoteSigner: config.web3SignerUrl,
|
|
62
|
+
publisher: publisherAddresses
|
|
63
|
+
});
|
|
64
|
+
const keyStore = {
|
|
65
|
+
schemaVersion: 1,
|
|
66
|
+
slasher: undefined,
|
|
67
|
+
prover: undefined,
|
|
68
|
+
remoteSigner: undefined,
|
|
69
|
+
validators: validatorKeyStores
|
|
70
|
+
};
|
|
71
|
+
return keyStore;
|
|
72
|
+
}
|
|
73
|
+
function createKeyStoreFromPrivateKeys(config) {
|
|
74
|
+
const validatorKeyStores = [];
|
|
75
|
+
const ethPrivateKeys = [];
|
|
76
|
+
const validatorKeys = config.validatorPrivateKeys ? config.validatorPrivateKeys.getValue() : [];
|
|
77
|
+
for(let i = 0; i < validatorKeys.length; i++){
|
|
78
|
+
const key = validatorKeys[i];
|
|
79
|
+
const ethPrivateKey = key;
|
|
80
|
+
ethPrivateKeys.push(ethPrivateKey);
|
|
81
|
+
}
|
|
82
|
+
if (!ethPrivateKeys.length) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const coinbase = config.coinbase ? config.coinbase.toString() : privateKeyToAddress(ethPrivateKeys[0]);
|
|
86
|
+
const feeRecipient = config.feeRecipient ? config.feeRecipient.toString() : AztecAddress.ZERO.toString();
|
|
87
|
+
const publisherKeys = config.publisherPrivateKeys ? config.publisherPrivateKeys.map((k)=>k.getValue()) : [];
|
|
88
|
+
validatorKeyStores.push({
|
|
89
|
+
attester: ethPrivateKeys,
|
|
90
|
+
feeRecipient: feeRecipient,
|
|
91
|
+
coinbase: coinbase,
|
|
92
|
+
remoteSigner: undefined,
|
|
93
|
+
publisher: publisherKeys
|
|
94
|
+
});
|
|
95
|
+
const keyStore = {
|
|
96
|
+
schemaVersion: 1,
|
|
97
|
+
slasher: undefined,
|
|
98
|
+
prover: undefined,
|
|
99
|
+
remoteSigner: undefined,
|
|
100
|
+
validators: validatorKeyStores
|
|
101
|
+
};
|
|
102
|
+
return keyStore;
|
|
103
|
+
}
|
|
104
|
+
export function createKeyStoreForValidator(config) {
|
|
105
|
+
if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
|
|
106
|
+
return createKeyStoreFromWeb3Signer(config);
|
|
107
|
+
}
|
|
108
|
+
return createKeyStoreFromPrivateKeys(config);
|
|
109
|
+
}
|
|
@@ -26,7 +26,7 @@ import { type BlockHeader, type GlobalVariableBuilder as GlobalVariableBuilderIn
|
|
|
26
26
|
import type { SingleValidatorStats, ValidatorsStats } from '@aztec/stdlib/validators';
|
|
27
27
|
import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
|
|
28
28
|
import { Sentinel } from '../sentinel/sentinel.js';
|
|
29
|
-
import type
|
|
29
|
+
import { type AztecNodeConfig } from './config.js';
|
|
30
30
|
/**
|
|
31
31
|
* The aztec node.
|
|
32
32
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/aztec-node/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,uBAAuB,EAAwB,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EACL,cAAc,EAEd,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAc,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/aztec-node/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,8 +9,8 @@ import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@azte
|
|
|
9
9
|
import { createBlobSinkClient } from '@aztec/blob-sink/client';
|
|
10
10
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
11
11
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { RegistryContract, RollupContract, createEthereumChain, getPublicClient } from '@aztec/ethereum';
|
|
13
|
+
import { createL1TxUtilsWithBlobsFromEthSigner } from '@aztec/ethereum/l1-tx-utils-with-blobs';
|
|
14
14
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
15
15
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
16
16
|
import { Fr } from '@aztec/foundation/fields';
|
|
@@ -20,6 +20,7 @@ import { SerialQueue } from '@aztec/foundation/queue';
|
|
|
20
20
|
import { count } from '@aztec/foundation/string';
|
|
21
21
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
22
22
|
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
23
|
+
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
|
|
23
24
|
import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
|
|
24
25
|
import { createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
25
26
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
@@ -36,10 +37,11 @@ import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@az
|
|
|
36
37
|
import { PublicSimulationOutput, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
37
38
|
import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
38
39
|
import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
39
|
-
import { createValidatorClient } from '@aztec/validator-client';
|
|
40
|
+
import { ValidatorClient, createValidatorClient } from '@aztec/validator-client';
|
|
40
41
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
41
42
|
import { createPublicClient, fallback, http } from 'viem';
|
|
42
43
|
import { createSentinel } from '../sentinel/factory.js';
|
|
44
|
+
import { createKeyStoreForValidator } from './config.js';
|
|
43
45
|
import { NodeMetrics } from './node_metrics.js';
|
|
44
46
|
/**
|
|
45
47
|
* The aztec node.
|
|
@@ -120,6 +122,28 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
120
122
|
logger: createLogger('node:blob-sink:client')
|
|
121
123
|
});
|
|
122
124
|
const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
125
|
+
// Build a key store from file if given or from environment otherwise
|
|
126
|
+
let keyStoreManager;
|
|
127
|
+
const keyStoreProvided = config.keyStoreDirectory !== undefined && config.keyStoreDirectory.length > 0;
|
|
128
|
+
if (keyStoreProvided) {
|
|
129
|
+
const keyStores = loadKeystores(config.keyStoreDirectory);
|
|
130
|
+
keyStoreManager = new KeystoreManager(mergeKeystores(keyStores));
|
|
131
|
+
} else {
|
|
132
|
+
const keyStore = createKeyStoreForValidator(config);
|
|
133
|
+
if (keyStore) {
|
|
134
|
+
keyStoreManager = new KeystoreManager(keyStore);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// If we are a validator, verify our configuration before doing too much more.
|
|
138
|
+
if (!config.disableValidator) {
|
|
139
|
+
if (keyStoreManager === undefined) {
|
|
140
|
+
throw new Error('Failed to create key store, a requirement for running a validator');
|
|
141
|
+
}
|
|
142
|
+
if (!keyStoreProvided) {
|
|
143
|
+
log.warn('KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS');
|
|
144
|
+
}
|
|
145
|
+
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager);
|
|
146
|
+
}
|
|
123
147
|
// validate that the actual chain id matches that specified in configuration
|
|
124
148
|
if (config.l1ChainId !== ethereumChain.chainInfo.id) {
|
|
125
149
|
throw new Error(`RPC URL configured for chain id ${ethereumChain.chainInfo.id} but expected id ${config.l1ChainId}`);
|
|
@@ -206,7 +230,8 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
206
230
|
epochCache,
|
|
207
231
|
blockBuilder,
|
|
208
232
|
blockSource: archiver,
|
|
209
|
-
l1ToL2MessageSource: archiver
|
|
233
|
+
l1ToL2MessageSource: archiver,
|
|
234
|
+
keyStoreManager
|
|
210
235
|
});
|
|
211
236
|
if (validatorClient) {
|
|
212
237
|
watchers.push(validatorClient);
|
|
@@ -216,17 +241,13 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
216
241
|
let sequencer;
|
|
217
242
|
let slasherClient;
|
|
218
243
|
if (!config.disableValidator) {
|
|
219
|
-
// This shouldn't happen, validators need a publisher private key.
|
|
220
|
-
const { publisherPrivateKey } = config;
|
|
221
|
-
if (!publisherPrivateKey?.getValue() || publisherPrivateKey?.getValue() === NULL_KEY) {
|
|
222
|
-
throw new Error('A publisher private key is required to run a validator');
|
|
223
|
-
}
|
|
224
244
|
// We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
|
|
225
245
|
// as they are executed when the node is selected as proposer.
|
|
226
246
|
slasherClient = await createSlasher(config, config.l1Contracts, getPublicClient(config), watchers, dateProvider, epochCache);
|
|
227
247
|
await slasherClient.start();
|
|
228
|
-
const
|
|
229
|
-
|
|
248
|
+
const l1TxUtils = keyStoreManager.createAllValidatorPublisherSigners().map((signer)=>{
|
|
249
|
+
return createL1TxUtilsWithBlobsFromEthSigner(publicClient, signer, log, dateProvider, config);
|
|
250
|
+
});
|
|
230
251
|
sequencer = await SequencerClient.new(config, {
|
|
231
252
|
// if deps were provided, they should override the defaults,
|
|
232
253
|
// or things that we created in this function
|
|
@@ -242,7 +263,8 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
242
263
|
l1ToL2MessageSource: archiver,
|
|
243
264
|
telemetry,
|
|
244
265
|
dateProvider,
|
|
245
|
-
blobSinkClient
|
|
266
|
+
blobSinkClient,
|
|
267
|
+
nodeKeyStore: keyStoreManager
|
|
246
268
|
});
|
|
247
269
|
}
|
|
248
270
|
if (!options.dontStartSequencer && sequencer) {
|
|
@@ -708,8 +730,8 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
708
730
|
const txHash = tx.getTxHash();
|
|
709
731
|
const blockNumber = await this.blockSource.getBlockNumber() + 1;
|
|
710
732
|
// If sequencer is not initialized, we just set these values to zero for simulation.
|
|
711
|
-
const coinbase =
|
|
712
|
-
const feeRecipient =
|
|
733
|
+
const coinbase = EthAddress.ZERO;
|
|
734
|
+
const feeRecipient = AztecAddress.ZERO;
|
|
713
735
|
const newGlobalVariables = await this.globalVariableBuilder.buildGlobalVariables(blockNumber, coinbase, feeRecipient);
|
|
714
736
|
const publicProcessorFactory = new PublicProcessorFactory(this.contractDataSource, new DateProvider(), this.telemetry);
|
|
715
737
|
this.log.verbose(`Simulating public calls for tx ${txHash}`, {
|
|
@@ -3,7 +3,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
3
3
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
4
4
|
import { type L2TipsStore } from '@aztec/kv-store/stores';
|
|
5
5
|
import type { P2PClient } from '@aztec/p2p';
|
|
6
|
-
import { type
|
|
6
|
+
import { type Watcher, type WatcherEmitter } from '@aztec/slasher';
|
|
7
7
|
import type { SlasherConfig } from '@aztec/slasher/config';
|
|
8
8
|
import { type L2BlockSource, L2BlockStream, type L2BlockStreamEvent, type L2BlockStreamEventHandler } from '@aztec/stdlib/block';
|
|
9
9
|
import type { SingleValidatorStats, ValidatorStats, ValidatorStatusHistory, ValidatorStatusInSlot, ValidatorStatusType, ValidatorsEpochPerformance, ValidatorsStats } from '@aztec/stdlib/validators';
|
|
@@ -37,7 +37,6 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
|
|
|
37
37
|
protected computeProvenPerformance(epoch: bigint): Promise<ValidatorsEpochPerformance>;
|
|
38
38
|
protected updateProvenPerformance(epoch: bigint, performance: ValidatorsEpochPerformance): Promise<void>;
|
|
39
39
|
protected handleProvenPerformance(epoch: bigint, performance: ValidatorsEpochPerformance): void;
|
|
40
|
-
shouldSlash({ validator, amount }: WantToSlashArgs): Promise<boolean>;
|
|
41
40
|
/**
|
|
42
41
|
* Process data for two L2 slots ago.
|
|
43
42
|
* Note that we do not process historical data, since we rely on p2p data for processing,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentinel.d.ts","sourceRoot":"","sources":["../../src/sentinel/sentinel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sentinel.d.ts","sourceRoot":"","sources":["../../src/sentinel/sentinel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAoC,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,KAAK,aAAa,EAClB,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAE/B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,0BAA0B,EAC1B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;6BAEI,UAAU,cAAc;AAAvE,qBAAa,QAAS,SAAQ,aAA2C,YAAW,yBAAyB,EAAE,OAAO;IAWlH,SAAS,CAAC,UAAU,EAAE,UAAU;IAChC,SAAS,CAAC,QAAQ,EAAE,aAAa;IACjC,SAAS,CAAC,GAAG,EAAE,SAAS;IACxB,SAAS,CAAC,KAAK,EAAE,aAAa;IAC9B,SAAS,CAAC,MAAM,EAAE,IAAI,CACpB,aAAa,EACX,uCAAuC,GACvC,8BAA8B,GAC9B,uCAAuC,GACvC,2BAA2B,GAC3B,wBAAwB,CAC3B;IACD,SAAS,CAAC,MAAM;IAtBlB,SAAS,CAAC,cAAc,EAAE,cAAc,CAAC;IACzC,SAAS,CAAC,WAAW,EAAG,aAAa,CAAC;IACtC,SAAS,CAAC,WAAW,EAAE,WAAW,CAAC;IAEnC,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,SAAS,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC,CAC/F;gBAGA,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,IAAI,CACpB,aAAa,EACX,uCAAuC,GACvC,8BAA8B,GAC9B,uCAAuC,GACvC,2BAA2B,GAC3B,wBAAwB,CAC3B,EACS,MAAM,yCAAgC;IAQ3C,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC;IAIrC,KAAK;IAKlB,kHAAkH;cAClG,IAAI;IAOb,IAAI;IAIE,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;cA2B7D,iBAAiB,CAAC,KAAK,EAAE,kBAAkB;cAoB3C,wBAAwB,CAAC,KAAK,EAAE,MAAM;IAoCtD,SAAS,CAAC,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,0BAA0B;IAIxF,SAAS,CAAC,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,0BAA0B;IAoBxF;;;;OAIG;IACU,IAAI;IAmBjB;;;;OAIG;cACa,gBAAgB,CAAC,WAAW,EAAE,MAAM;IAkCpD;;;OAGG;cACa,WAAW,CAAC,IAAI,EAAE,MAAM;IAexC,0CAA0C;cAC1B,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE;;;IAwD1G,wDAAwD;IACxD,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,MAAM,EAAE,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAIxG,0DAA0D;IAC7C,YAAY,CAAC,EACxB,QAAQ,EAAE,SAAS,EACnB,MAAM,EAAE,OAAO,GAChB,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,eAAe,CAAC;IAkBzE,6CAA6C;IAChC,iBAAiB,CAC5B,gBAAgB,EAAE,UAAU,EAC5B,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAoC5C,SAAS,CAAC,wBAAwB,CAChC,OAAO,EAAE,KAAK,MAAM,EAAE,EACtB,UAAU,EAAE,sBAAsB,EAClC,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,cAAc;IAgBjB,SAAS,CAAC,aAAa,CACrB,OAAO,EAAE,sBAAsB,EAC/B,iBAAiB,EAAE,mBAAmB,EACtC,MAAM,EAAE,qBAAqB;;;;;IAW/B,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;;;;;CAOnD"}
|
|
@@ -3,8 +3,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
5
5
|
import { L2TipsMemoryStore } from '@aztec/kv-store/stores';
|
|
6
|
-
import { OffenseType } from '@aztec/slasher';
|
|
7
|
-
import { WANT_TO_SLASH_EVENT } from '@aztec/slasher';
|
|
6
|
+
import { OffenseType, WANT_TO_SLASH_EVENT } from '@aztec/slasher';
|
|
8
7
|
import { L2BlockStream, getAttestationsFromPublishedL2Block } from '@aztec/stdlib/block';
|
|
9
8
|
import { getEpochAtSlot, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
10
9
|
import EventEmitter from 'node:events';
|
|
@@ -84,9 +83,9 @@ export class Sentinel extends EventEmitter {
|
|
|
84
83
|
return;
|
|
85
84
|
}
|
|
86
85
|
const epoch = getEpochAtSlot(block.header.getSlot(), await this.archiver.getL1Constants());
|
|
87
|
-
this.logger.
|
|
86
|
+
this.logger.debug(`Computing proven performance for epoch ${epoch}`);
|
|
88
87
|
const performance = await this.computeProvenPerformance(epoch);
|
|
89
|
-
this.logger.info(`
|
|
88
|
+
this.logger.info(`Computed proven performance for epoch ${epoch}`, performance);
|
|
90
89
|
await this.updateProvenPerformance(epoch, performance);
|
|
91
90
|
this.handleProvenPerformance(epoch, performance);
|
|
92
91
|
}
|
|
@@ -143,33 +142,13 @@ export class Sentinel extends EventEmitter {
|
|
|
143
142
|
offenseType: OffenseType.INACTIVITY,
|
|
144
143
|
epochOrSlot: epoch
|
|
145
144
|
}));
|
|
146
|
-
this.logger.info(`Criminals: ${criminals.length}`, {
|
|
147
|
-
args
|
|
148
|
-
});
|
|
149
145
|
if (criminals.length > 0) {
|
|
146
|
+
this.logger.info(`Identified ${criminals.length} validators to slash due to inactivity`, {
|
|
147
|
+
args
|
|
148
|
+
});
|
|
150
149
|
this.emit(WANT_TO_SLASH_EVENT, args);
|
|
151
150
|
}
|
|
152
151
|
}
|
|
153
|
-
async shouldSlash({ validator, amount }) {
|
|
154
|
-
const l1Constants = this.epochCache.getL1Constants();
|
|
155
|
-
const ttlL2Slots = this.config.slashPayloadTtlSeconds / l1Constants.slotDuration;
|
|
156
|
-
const ttlEpochs = BigInt(Math.ceil(ttlL2Slots / l1Constants.epochDuration));
|
|
157
|
-
const currentEpoch = this.epochCache.getEpochAndSlotNow().epoch;
|
|
158
|
-
const performance = await this.store.getProvenPerformance(validator);
|
|
159
|
-
const isCriminal = performance.filter((p)=>p.epoch >= currentEpoch - ttlEpochs).findIndex((p)=>p.missed / p.total >= this.config.slashInactivitySignalTargetPercentage) !== -1;
|
|
160
|
-
if (isCriminal) {
|
|
161
|
-
if (amount <= this.config.slashInactivityMaxPenalty) {
|
|
162
|
-
return true;
|
|
163
|
-
} else {
|
|
164
|
-
this.logger.warn(`Validator ${validator} is a criminal but the penalty is too high`, {
|
|
165
|
-
amount,
|
|
166
|
-
maxPenalty: this.config.slashInactivityMaxPenalty
|
|
167
|
-
});
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
152
|
/**
|
|
174
153
|
* Process data for two L2 slots ago.
|
|
175
154
|
* Note that we do not process historical data, since we rely on p2p data for processing,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/aztec-node",
|
|
3
|
-
"version": "2.0.0-nightly.
|
|
3
|
+
"version": "2.0.0-nightly.20250828",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -66,28 +66,29 @@
|
|
|
66
66
|
]
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@aztec/archiver": "2.0.0-nightly.
|
|
70
|
-
"@aztec/bb-prover": "2.0.0-nightly.
|
|
71
|
-
"@aztec/blob-sink": "2.0.0-nightly.
|
|
72
|
-
"@aztec/constants": "2.0.0-nightly.
|
|
73
|
-
"@aztec/epoch-cache": "2.0.0-nightly.
|
|
74
|
-
"@aztec/ethereum": "2.0.0-nightly.
|
|
75
|
-
"@aztec/foundation": "2.0.0-nightly.
|
|
76
|
-
"@aztec/kv-store": "2.0.0-nightly.
|
|
77
|
-
"@aztec/l1-artifacts": "2.0.0-nightly.
|
|
78
|
-
"@aztec/merkle-tree": "2.0.0-nightly.
|
|
79
|
-
"@aztec/node-
|
|
80
|
-
"@aztec/
|
|
81
|
-
"@aztec/
|
|
82
|
-
"@aztec/
|
|
83
|
-
"@aztec/
|
|
84
|
-
"@aztec/
|
|
85
|
-
"@aztec/
|
|
86
|
-
"@aztec/
|
|
87
|
-
"@aztec/
|
|
88
|
-
"@aztec/
|
|
89
|
-
"@aztec/
|
|
90
|
-
"@aztec/
|
|
69
|
+
"@aztec/archiver": "2.0.0-nightly.20250828",
|
|
70
|
+
"@aztec/bb-prover": "2.0.0-nightly.20250828",
|
|
71
|
+
"@aztec/blob-sink": "2.0.0-nightly.20250828",
|
|
72
|
+
"@aztec/constants": "2.0.0-nightly.20250828",
|
|
73
|
+
"@aztec/epoch-cache": "2.0.0-nightly.20250828",
|
|
74
|
+
"@aztec/ethereum": "2.0.0-nightly.20250828",
|
|
75
|
+
"@aztec/foundation": "2.0.0-nightly.20250828",
|
|
76
|
+
"@aztec/kv-store": "2.0.0-nightly.20250828",
|
|
77
|
+
"@aztec/l1-artifacts": "2.0.0-nightly.20250828",
|
|
78
|
+
"@aztec/merkle-tree": "2.0.0-nightly.20250828",
|
|
79
|
+
"@aztec/node-keystore": "2.0.0-nightly.20250828",
|
|
80
|
+
"@aztec/node-lib": "2.0.0-nightly.20250828",
|
|
81
|
+
"@aztec/noir-protocol-circuits-types": "2.0.0-nightly.20250828",
|
|
82
|
+
"@aztec/p2p": "2.0.0-nightly.20250828",
|
|
83
|
+
"@aztec/protocol-contracts": "2.0.0-nightly.20250828",
|
|
84
|
+
"@aztec/prover-client": "2.0.0-nightly.20250828",
|
|
85
|
+
"@aztec/sequencer-client": "2.0.0-nightly.20250828",
|
|
86
|
+
"@aztec/simulator": "2.0.0-nightly.20250828",
|
|
87
|
+
"@aztec/slasher": "2.0.0-nightly.20250828",
|
|
88
|
+
"@aztec/stdlib": "2.0.0-nightly.20250828",
|
|
89
|
+
"@aztec/telemetry-client": "2.0.0-nightly.20250828",
|
|
90
|
+
"@aztec/validator-client": "2.0.0-nightly.20250828",
|
|
91
|
+
"@aztec/world-state": "2.0.0-nightly.20250828",
|
|
91
92
|
"koa": "^2.16.1",
|
|
92
93
|
"koa-router": "^12.0.0",
|
|
93
94
|
"tslib": "^2.4.0",
|
package/src/aztec-node/config.ts
CHANGED
|
@@ -7,16 +7,34 @@ import {
|
|
|
7
7
|
} from '@aztec/ethereum';
|
|
8
8
|
import { type ConfigMappingsType, booleanConfigHelper, getConfigFromMappings } from '@aztec/foundation/config';
|
|
9
9
|
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
10
|
+
import {
|
|
11
|
+
type AztecAddressHex,
|
|
12
|
+
type EthAddressHex,
|
|
13
|
+
type EthPrivateKey,
|
|
14
|
+
type EthRemoteSignerAccount,
|
|
15
|
+
type Hex,
|
|
16
|
+
type KeyStore,
|
|
17
|
+
type KeyStoreConfig,
|
|
18
|
+
type ValidatorKeyStore,
|
|
19
|
+
keyStoreConfigMappings,
|
|
20
|
+
} from '@aztec/node-keystore';
|
|
10
21
|
import { type SharedNodeConfig, sharedNodeConfigMappings } from '@aztec/node-lib/config';
|
|
11
22
|
import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
|
|
12
23
|
import { type ProverClientUserConfig, proverClientConfigMappings } from '@aztec/prover-client/config';
|
|
13
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
type SequencerClientConfig,
|
|
26
|
+
type TxSenderConfig,
|
|
27
|
+
sequencerClientConfigMappings,
|
|
28
|
+
} from '@aztec/sequencer-client/config';
|
|
14
29
|
import { slasherConfigMappings } from '@aztec/slasher';
|
|
30
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
31
|
import { type NodeRPCConfig, nodeRpcConfigMappings } from '@aztec/stdlib/config';
|
|
16
32
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
17
33
|
import { type ValidatorClientConfig, validatorClientConfigMappings } from '@aztec/validator-client/config';
|
|
18
34
|
import { type WorldStateConfig, worldStateConfigMappings } from '@aztec/world-state/config';
|
|
19
35
|
|
|
36
|
+
import { privateKeyToAddress } from 'viem/accounts';
|
|
37
|
+
|
|
20
38
|
import { type SentinelConfig, sentinelConfigMappings } from '../sentinel/config.js';
|
|
21
39
|
|
|
22
40
|
export { sequencerClientConfigMappings, type SequencerClientConfig };
|
|
@@ -32,6 +50,7 @@ export type AztecNodeConfig = ArchiverConfig &
|
|
|
32
50
|
Pick<ProverClientUserConfig, 'bbBinaryPath' | 'bbWorkingDirectory' | 'realProofs'> &
|
|
33
51
|
P2PConfig &
|
|
34
52
|
DataStoreConfig &
|
|
53
|
+
KeyStoreConfig &
|
|
35
54
|
SentinelConfig &
|
|
36
55
|
SharedNodeConfig &
|
|
37
56
|
GenesisStateConfig &
|
|
@@ -45,6 +64,7 @@ export type AztecNodeConfig = ArchiverConfig &
|
|
|
45
64
|
|
|
46
65
|
export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
|
|
47
66
|
...dataConfigMappings,
|
|
67
|
+
...keyStoreConfigMappings,
|
|
48
68
|
...archiverConfigMappings,
|
|
49
69
|
...sequencerClientConfigMappings,
|
|
50
70
|
...validatorClientConfigMappings,
|
|
@@ -74,3 +94,90 @@ export const aztecNodeConfigMappings: ConfigMappingsType<AztecNodeConfig> = {
|
|
|
74
94
|
export function getConfigEnvVars(): AztecNodeConfig {
|
|
75
95
|
return getConfigFromMappings<AztecNodeConfig>(aztecNodeConfigMappings);
|
|
76
96
|
}
|
|
97
|
+
|
|
98
|
+
type ConfigRequiredToBuildKeyStore = TxSenderConfig & SequencerClientConfig & SharedNodeConfig & ValidatorClientConfig;
|
|
99
|
+
|
|
100
|
+
function createKeyStoreFromWeb3Signer(config: ConfigRequiredToBuildKeyStore) {
|
|
101
|
+
const validatorKeyStores: ValidatorKeyStore[] = [];
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
config.web3SignerUrl === undefined ||
|
|
105
|
+
config.web3SignerUrl.length === 0 ||
|
|
106
|
+
config.validatorAddresses === undefined ||
|
|
107
|
+
config.validatorAddresses.length === 0
|
|
108
|
+
) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
const coinbase = config.coinbase ? config.coinbase.toString() : config.validatorAddresses[0].toString();
|
|
112
|
+
const feeRecipient = config.feeRecipient ? config.feeRecipient.toString() : AztecAddress.ZERO.toString();
|
|
113
|
+
|
|
114
|
+
const publisherAddresses =
|
|
115
|
+
config.publisherAddresses && config.publisherAddresses.length > 0
|
|
116
|
+
? config.publisherAddresses.map(k => k.toChecksumString() as EthRemoteSignerAccount)
|
|
117
|
+
: [];
|
|
118
|
+
|
|
119
|
+
const attestors = config.validatorAddresses.map(k => k.toChecksumString() as EthRemoteSignerAccount);
|
|
120
|
+
|
|
121
|
+
validatorKeyStores.push({
|
|
122
|
+
attester: attestors,
|
|
123
|
+
feeRecipient: feeRecipient as AztecAddressHex,
|
|
124
|
+
coinbase: coinbase as EthAddressHex,
|
|
125
|
+
remoteSigner: config.web3SignerUrl,
|
|
126
|
+
publisher: publisherAddresses,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const keyStore: KeyStore = {
|
|
130
|
+
schemaVersion: 1,
|
|
131
|
+
slasher: undefined,
|
|
132
|
+
prover: undefined,
|
|
133
|
+
remoteSigner: undefined,
|
|
134
|
+
validators: validatorKeyStores,
|
|
135
|
+
};
|
|
136
|
+
return keyStore;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function createKeyStoreFromPrivateKeys(config: ConfigRequiredToBuildKeyStore) {
|
|
140
|
+
const validatorKeyStores: ValidatorKeyStore[] = [];
|
|
141
|
+
const ethPrivateKeys: EthPrivateKey[] = [];
|
|
142
|
+
const validatorKeys = config.validatorPrivateKeys ? config.validatorPrivateKeys.getValue() : [];
|
|
143
|
+
for (let i = 0; i < validatorKeys.length; i++) {
|
|
144
|
+
const key = validatorKeys[i];
|
|
145
|
+
const ethPrivateKey: EthPrivateKey = key as Hex<32>;
|
|
146
|
+
ethPrivateKeys.push(ethPrivateKey);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (!ethPrivateKeys.length) {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
const coinbase = config.coinbase ? config.coinbase.toString() : privateKeyToAddress(ethPrivateKeys[0]);
|
|
153
|
+
const feeRecipient = config.feeRecipient ? config.feeRecipient.toString() : AztecAddress.ZERO.toString();
|
|
154
|
+
|
|
155
|
+
const publisherKeys = config.publisherPrivateKeys
|
|
156
|
+
? config.publisherPrivateKeys.map(k => k.getValue() as EthPrivateKey)
|
|
157
|
+
: [];
|
|
158
|
+
|
|
159
|
+
validatorKeyStores.push({
|
|
160
|
+
attester: ethPrivateKeys,
|
|
161
|
+
feeRecipient: feeRecipient as AztecAddressHex,
|
|
162
|
+
coinbase: coinbase as EthAddressHex,
|
|
163
|
+
remoteSigner: undefined,
|
|
164
|
+
publisher: publisherKeys,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const keyStore: KeyStore = {
|
|
168
|
+
schemaVersion: 1,
|
|
169
|
+
slasher: undefined,
|
|
170
|
+
prover: undefined,
|
|
171
|
+
remoteSigner: undefined,
|
|
172
|
+
validators: validatorKeyStores,
|
|
173
|
+
};
|
|
174
|
+
return keyStore;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function createKeyStoreForValidator(config: TxSenderConfig & SequencerClientConfig & SharedNodeConfig) {
|
|
178
|
+
if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
|
|
179
|
+
return createKeyStoreFromWeb3Signer(config);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return createKeyStoreFromPrivateKeys(config);
|
|
183
|
+
}
|
package/src/aztec-node/server.ts
CHANGED
|
@@ -11,15 +11,14 @@ import {
|
|
|
11
11
|
} from '@aztec/constants';
|
|
12
12
|
import { EpochCache, type EpochCacheInterface } from '@aztec/epoch-cache';
|
|
13
13
|
import {
|
|
14
|
+
type EthSigner,
|
|
14
15
|
type L1ContractAddresses,
|
|
15
|
-
NULL_KEY,
|
|
16
16
|
RegistryContract,
|
|
17
17
|
RollupContract,
|
|
18
18
|
createEthereumChain,
|
|
19
|
-
createExtendedL1Client,
|
|
20
19
|
getPublicClient,
|
|
21
20
|
} from '@aztec/ethereum';
|
|
22
|
-
import {
|
|
21
|
+
import { createL1TxUtilsWithBlobsFromEthSigner } from '@aztec/ethereum/l1-tx-utils-with-blobs';
|
|
23
22
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
24
23
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
25
24
|
import { Fr } from '@aztec/foundation/fields';
|
|
@@ -29,6 +28,7 @@ import { SerialQueue } from '@aztec/foundation/queue';
|
|
|
29
28
|
import { count } from '@aztec/foundation/string';
|
|
30
29
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
31
30
|
import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
|
|
31
|
+
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
|
|
32
32
|
import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
|
|
33
33
|
import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
34
34
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
@@ -108,14 +108,14 @@ import {
|
|
|
108
108
|
getTelemetryClient,
|
|
109
109
|
trackSpan,
|
|
110
110
|
} from '@aztec/telemetry-client';
|
|
111
|
-
import { createValidatorClient } from '@aztec/validator-client';
|
|
111
|
+
import { ValidatorClient, createValidatorClient } from '@aztec/validator-client';
|
|
112
112
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
113
113
|
|
|
114
114
|
import { createPublicClient, fallback, http } from 'viem';
|
|
115
115
|
|
|
116
116
|
import { createSentinel } from '../sentinel/factory.js';
|
|
117
117
|
import { Sentinel } from '../sentinel/sentinel.js';
|
|
118
|
-
import type
|
|
118
|
+
import { type AztecNodeConfig, createKeyStoreForValidator } from './config.js';
|
|
119
119
|
import { NodeMetrics } from './node_metrics.js';
|
|
120
120
|
|
|
121
121
|
/**
|
|
@@ -199,6 +199,32 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
199
199
|
deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('node:blob-sink:client') });
|
|
200
200
|
const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
201
201
|
|
|
202
|
+
// Build a key store from file if given or from environment otherwise
|
|
203
|
+
let keyStoreManager: KeystoreManager | undefined;
|
|
204
|
+
const keyStoreProvided = config.keyStoreDirectory !== undefined && config.keyStoreDirectory.length > 0;
|
|
205
|
+
if (keyStoreProvided) {
|
|
206
|
+
const keyStores = loadKeystores(config.keyStoreDirectory!);
|
|
207
|
+
keyStoreManager = new KeystoreManager(mergeKeystores(keyStores));
|
|
208
|
+
} else {
|
|
209
|
+
const keyStore = createKeyStoreForValidator(config);
|
|
210
|
+
if (keyStore) {
|
|
211
|
+
keyStoreManager = new KeystoreManager(keyStore);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// If we are a validator, verify our configuration before doing too much more.
|
|
216
|
+
if (!config.disableValidator) {
|
|
217
|
+
if (keyStoreManager === undefined) {
|
|
218
|
+
throw new Error('Failed to create key store, a requirement for running a validator');
|
|
219
|
+
}
|
|
220
|
+
if (!keyStoreProvided) {
|
|
221
|
+
log.warn(
|
|
222
|
+
'KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS',
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager);
|
|
226
|
+
}
|
|
227
|
+
|
|
202
228
|
// validate that the actual chain id matches that specified in configuration
|
|
203
229
|
if (config.l1ChainId !== ethereumChain.chainInfo.id) {
|
|
204
230
|
throw new Error(
|
|
@@ -331,6 +357,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
331
357
|
blockBuilder,
|
|
332
358
|
blockSource: archiver,
|
|
333
359
|
l1ToL2MessageSource: archiver,
|
|
360
|
+
keyStoreManager,
|
|
334
361
|
});
|
|
335
362
|
|
|
336
363
|
if (validatorClient) {
|
|
@@ -344,12 +371,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
344
371
|
let slasherClient: SlasherClientInterface | undefined;
|
|
345
372
|
|
|
346
373
|
if (!config.disableValidator) {
|
|
347
|
-
// This shouldn't happen, validators need a publisher private key.
|
|
348
|
-
const { publisherPrivateKey } = config;
|
|
349
|
-
if (!publisherPrivateKey?.getValue() || publisherPrivateKey?.getValue() === NULL_KEY) {
|
|
350
|
-
throw new Error('A publisher private key is required to run a validator');
|
|
351
|
-
}
|
|
352
|
-
|
|
353
374
|
// We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
|
|
354
375
|
// as they are executed when the node is selected as proposer.
|
|
355
376
|
slasherClient = await createSlasher(
|
|
@@ -362,12 +383,9 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
362
383
|
);
|
|
363
384
|
await slasherClient.start();
|
|
364
385
|
|
|
365
|
-
const
|
|
366
|
-
config
|
|
367
|
-
|
|
368
|
-
ethereumChain.chainInfo,
|
|
369
|
-
);
|
|
370
|
-
const l1TxUtils = new L1TxUtilsWithBlobs(l1Client, log, dateProvider, config);
|
|
386
|
+
const l1TxUtils = keyStoreManager!.createAllValidatorPublisherSigners().map((signer: EthSigner) => {
|
|
387
|
+
return createL1TxUtilsWithBlobsFromEthSigner(publicClient, signer, log, dateProvider, config);
|
|
388
|
+
});
|
|
371
389
|
|
|
372
390
|
sequencer = await SequencerClient.new(config, {
|
|
373
391
|
// if deps were provided, they should override the defaults,
|
|
@@ -385,6 +403,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
385
403
|
telemetry,
|
|
386
404
|
dateProvider,
|
|
387
405
|
blobSinkClient,
|
|
406
|
+
nodeKeyStore: keyStoreManager!,
|
|
388
407
|
});
|
|
389
408
|
}
|
|
390
409
|
|
|
@@ -1015,8 +1034,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1015
1034
|
const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
|
|
1016
1035
|
|
|
1017
1036
|
// If sequencer is not initialized, we just set these values to zero for simulation.
|
|
1018
|
-
const coinbase =
|
|
1019
|
-
const feeRecipient =
|
|
1037
|
+
const coinbase = EthAddress.ZERO;
|
|
1038
|
+
const feeRecipient = AztecAddress.ZERO;
|
|
1020
1039
|
|
|
1021
1040
|
const newGlobalVariables = await this.globalVariableBuilder.buildGlobalVariables(
|
|
1022
1041
|
blockNumber,
|
package/src/sentinel/sentinel.ts
CHANGED
|
@@ -5,8 +5,7 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
5
5
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
6
6
|
import { L2TipsMemoryStore, type L2TipsStore } from '@aztec/kv-store/stores';
|
|
7
7
|
import type { P2PClient } from '@aztec/p2p';
|
|
8
|
-
import { OffenseType } from '@aztec/slasher';
|
|
9
|
-
import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '@aztec/slasher';
|
|
8
|
+
import { OffenseType, WANT_TO_SLASH_EVENT, type Watcher, type WatcherEmitter } from '@aztec/slasher';
|
|
10
9
|
import type { SlasherConfig } from '@aztec/slasher/config';
|
|
11
10
|
import {
|
|
12
11
|
type L2BlockSource,
|
|
@@ -121,9 +120,9 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
const epoch = getEpochAtSlot(block.header.getSlot(), await this.archiver.getL1Constants());
|
|
124
|
-
this.logger.
|
|
123
|
+
this.logger.debug(`Computing proven performance for epoch ${epoch}`);
|
|
125
124
|
const performance = await this.computeProvenPerformance(epoch);
|
|
126
|
-
this.logger.info(`
|
|
125
|
+
this.logger.info(`Computed proven performance for epoch ${epoch}`, performance);
|
|
127
126
|
|
|
128
127
|
await this.updateProvenPerformance(epoch, performance);
|
|
129
128
|
this.handleProvenPerformance(epoch, performance);
|
|
@@ -183,38 +182,12 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
|
|
|
183
182
|
epochOrSlot: epoch,
|
|
184
183
|
}));
|
|
185
184
|
|
|
186
|
-
this.logger.info(`Criminals: ${criminals.length}`, { args });
|
|
187
|
-
|
|
188
185
|
if (criminals.length > 0) {
|
|
186
|
+
this.logger.info(`Identified ${criminals.length} validators to slash due to inactivity`, { args });
|
|
189
187
|
this.emit(WANT_TO_SLASH_EVENT, args);
|
|
190
188
|
}
|
|
191
189
|
}
|
|
192
190
|
|
|
193
|
-
public async shouldSlash({ validator, amount }: WantToSlashArgs): Promise<boolean> {
|
|
194
|
-
const l1Constants = this.epochCache.getL1Constants();
|
|
195
|
-
const ttlL2Slots = this.config.slashPayloadTtlSeconds / l1Constants.slotDuration;
|
|
196
|
-
const ttlEpochs = BigInt(Math.ceil(ttlL2Slots / l1Constants.epochDuration));
|
|
197
|
-
|
|
198
|
-
const currentEpoch = this.epochCache.getEpochAndSlotNow().epoch;
|
|
199
|
-
const performance = await this.store.getProvenPerformance(validator);
|
|
200
|
-
const isCriminal =
|
|
201
|
-
performance
|
|
202
|
-
.filter(p => p.epoch >= currentEpoch - ttlEpochs)
|
|
203
|
-
.findIndex(p => p.missed / p.total >= this.config.slashInactivitySignalTargetPercentage) !== -1;
|
|
204
|
-
if (isCriminal) {
|
|
205
|
-
if (amount <= this.config.slashInactivityMaxPenalty) {
|
|
206
|
-
return true;
|
|
207
|
-
} else {
|
|
208
|
-
this.logger.warn(`Validator ${validator} is a criminal but the penalty is too high`, {
|
|
209
|
-
amount,
|
|
210
|
-
maxPenalty: this.config.slashInactivityMaxPenalty,
|
|
211
|
-
});
|
|
212
|
-
return false;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
191
|
/**
|
|
219
192
|
* Process data for two L2 slots ago.
|
|
220
193
|
* Note that we do not process historical data, since we rely on p2p data for processing,
|