@aztec/prover-node 3.0.0-canary.a9708bd → 3.0.0-devnet.2-patch.1
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/actions/download-epoch-proving-job.d.ts +4 -4
- package/dest/actions/index.d.ts +1 -1
- package/dest/actions/rerun-epoch-proving-job.d.ts +2 -2
- package/dest/actions/upload-epoch-proof-failure.d.ts +1 -1
- package/dest/bin/run-failed-epoch.d.ts +1 -1
- package/dest/bin/run-failed-epoch.js +1 -1
- package/dest/config.d.ts +4 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +19 -14
- package/dest/factory.d.ts +2 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +18 -7
- package/dest/index.d.ts +1 -1
- package/dest/job/epoch-proving-job-data.d.ts +8 -6
- package/dest/job/epoch-proving-job-data.d.ts.map +1 -1
- package/dest/job/epoch-proving-job-data.js +25 -18
- package/dest/job/epoch-proving-job.d.ts +11 -16
- package/dest/job/epoch-proving-job.d.ts.map +1 -1
- package/dest/job/epoch-proving-job.js +107 -65
- package/dest/metrics.d.ts +4 -3
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +9 -3
- package/dest/monitors/epoch-monitor.d.ts +5 -2
- package/dest/monitors/epoch-monitor.d.ts.map +1 -1
- package/dest/monitors/epoch-monitor.js +10 -1
- package/dest/monitors/index.d.ts +1 -1
- package/dest/prover-node-publisher.d.ts +9 -10
- package/dest/prover-node-publisher.d.ts.map +1 -1
- package/dest/prover-node-publisher.js +51 -52
- package/dest/prover-node.d.ts +8 -7
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +39 -32
- package/dest/prover-publisher-factory.d.ts +6 -2
- package/dest/prover-publisher-factory.d.ts.map +1 -1
- package/dest/prover-publisher-factory.js +6 -0
- package/dest/test/index.d.ts +1 -1
- package/dest/test/index.d.ts.map +1 -1
- package/package.json +26 -25
- package/src/bin/run-failed-epoch.ts +2 -2
- package/src/config.ts +30 -29
- package/src/factory.ts +22 -14
- package/src/job/epoch-proving-job-data.ts +31 -25
- package/src/job/epoch-proving-job.ts +138 -82
- package/src/metrics.ts +16 -4
- package/src/monitors/epoch-monitor.ts +15 -5
- package/src/prover-node-publisher.ts +73 -72
- package/src/prover-node.ts +51 -44
- package/src/prover-publisher-factory.ts +12 -1
package/src/config.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { type ArchiverConfig, archiverConfigMappings } from '@aztec/archiver/config';
|
|
2
2
|
import type { ACVMConfig, BBConfig } from '@aztec/bb-prover/config';
|
|
3
|
-
import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethereum';
|
|
4
|
-
import { type ConfigMappingsType, getConfigFromMappings, numberConfigHelper } from '@aztec/foundation/config';
|
|
5
|
-
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
3
|
+
import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethereum/config';
|
|
6
4
|
import {
|
|
7
|
-
type
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from '@aztec/node-keystore';
|
|
5
|
+
type ConfigMappingsType,
|
|
6
|
+
booleanConfigHelper,
|
|
7
|
+
getConfigFromMappings,
|
|
8
|
+
numberConfigHelper,
|
|
9
|
+
} from '@aztec/foundation/config';
|
|
10
|
+
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
11
|
+
import { type KeyStore, type KeyStoreConfig, ethPrivateKeySchema, keyStoreConfigMappings } from '@aztec/node-keystore';
|
|
14
12
|
import { type SharedNodeConfig, sharedNodeConfigMappings } from '@aztec/node-lib/config';
|
|
15
13
|
import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
|
|
16
14
|
import {
|
|
@@ -45,6 +43,8 @@ export type SpecificProverNodeConfig = {
|
|
|
45
43
|
proverNodePollingIntervalMs: number;
|
|
46
44
|
proverNodeMaxParallelBlocksPerEpoch: number;
|
|
47
45
|
proverNodeFailedEpochStore: string | undefined;
|
|
46
|
+
proverNodeEpochProvingDelayMs: number | undefined;
|
|
47
|
+
proverNodeDisableProofPublish?: boolean;
|
|
48
48
|
txGatheringTimeoutMs: number;
|
|
49
49
|
txGatheringIntervalMs: number;
|
|
50
50
|
txGatheringBatchSize: number;
|
|
@@ -72,6 +72,10 @@ const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeCon
|
|
|
72
72
|
description: 'File store where to upload node state when an epoch fails to be proven',
|
|
73
73
|
defaultValue: undefined,
|
|
74
74
|
},
|
|
75
|
+
proverNodeEpochProvingDelayMs: {
|
|
76
|
+
description: 'Optional delay in milliseconds to wait before proving a new epoch',
|
|
77
|
+
defaultValue: undefined,
|
|
78
|
+
},
|
|
75
79
|
txGatheringIntervalMs: {
|
|
76
80
|
env: 'PROVER_NODE_TX_GATHERING_INTERVAL_MS',
|
|
77
81
|
description: 'How often to check that tx data is available',
|
|
@@ -92,6 +96,11 @@ const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeCon
|
|
|
92
96
|
description: 'How long to wait for tx data to be available before giving up',
|
|
93
97
|
...numberConfigHelper(120_000),
|
|
94
98
|
},
|
|
99
|
+
proverNodeDisableProofPublish: {
|
|
100
|
+
env: 'PROVER_NODE_DISABLE_PROOF_PUBLISH',
|
|
101
|
+
description: 'Whether the prover node skips publishing proofs to L1',
|
|
102
|
+
...booleanConfigHelper(false),
|
|
103
|
+
},
|
|
95
104
|
};
|
|
96
105
|
|
|
97
106
|
export const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConfig> = {
|
|
@@ -125,19 +134,14 @@ export function getProverNodeAgentConfigFromEnv(): ProverAgentConfig & BBConfig
|
|
|
125
134
|
};
|
|
126
135
|
}
|
|
127
136
|
|
|
128
|
-
function createKeyStoreFromWeb3Signer(config: ProverNodeConfig) {
|
|
129
|
-
// See what we have been given for proverId.
|
|
130
|
-
const proverId = config.proverId ? (config.proverId.toString() as EthAddressHex) : undefined;
|
|
131
|
-
|
|
137
|
+
function createKeyStoreFromWeb3Signer(config: ProverNodeConfig): KeyStore | undefined {
|
|
132
138
|
// If we don't have a valid prover Id then we can't build a valid key store with remote signers
|
|
133
|
-
if (proverId === undefined) {
|
|
139
|
+
if (config.proverId === undefined) {
|
|
134
140
|
return undefined;
|
|
135
141
|
}
|
|
136
142
|
|
|
137
143
|
// Also, we need at least one publisher address.
|
|
138
|
-
const publishers = config.publisherAddresses
|
|
139
|
-
? config.publisherAddresses.map(k => k.toChecksumString() as EthRemoteSignerAccount)
|
|
140
|
-
: [];
|
|
144
|
+
const publishers = config.publisherAddresses ?? [];
|
|
141
145
|
|
|
142
146
|
if (publishers.length === 0) {
|
|
143
147
|
return undefined;
|
|
@@ -147,7 +151,7 @@ function createKeyStoreFromWeb3Signer(config: ProverNodeConfig) {
|
|
|
147
151
|
schemaVersion: 1,
|
|
148
152
|
slasher: undefined,
|
|
149
153
|
prover: {
|
|
150
|
-
id: proverId,
|
|
154
|
+
id: config.proverId,
|
|
151
155
|
publisher: publishers,
|
|
152
156
|
},
|
|
153
157
|
remoteSigner: config.web3SignerUrl,
|
|
@@ -156,10 +160,10 @@ function createKeyStoreFromWeb3Signer(config: ProverNodeConfig) {
|
|
|
156
160
|
return keyStore;
|
|
157
161
|
}
|
|
158
162
|
|
|
159
|
-
function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
|
|
163
|
+
function createKeyStoreFromPublisherKeys(config: ProverNodeConfig): KeyStore | undefined {
|
|
160
164
|
// Extract the publisher keys from the provided config.
|
|
161
165
|
const publisherKeys = config.publisherPrivateKeys
|
|
162
|
-
? config.publisherPrivateKeys.map(k => k.getValue()
|
|
166
|
+
? config.publisherPrivateKeys.map(k => ethPrivateKeySchema.parse(k.getValue()))
|
|
163
167
|
: [];
|
|
164
168
|
|
|
165
169
|
// There must be at least 1.
|
|
@@ -167,9 +171,6 @@ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
|
|
|
167
171
|
return undefined;
|
|
168
172
|
}
|
|
169
173
|
|
|
170
|
-
// Now see what we have been given for proverId.
|
|
171
|
-
const proverId = config.proverId ? (config.proverId.toString() as EthAddressHex) : undefined;
|
|
172
|
-
|
|
173
174
|
// If we have a valid proverId then create a prover key store of the form { id, publisher: [publisherKeys] }
|
|
174
175
|
// Otherwise create one of the form ("0x12345678....." as EthAccount).
|
|
175
176
|
|
|
@@ -177,11 +178,11 @@ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
|
|
|
177
178
|
schemaVersion: 1,
|
|
178
179
|
slasher: undefined,
|
|
179
180
|
prover:
|
|
180
|
-
proverId === undefined
|
|
181
|
-
?
|
|
181
|
+
config.proverId === undefined
|
|
182
|
+
? publisherKeys[0]
|
|
182
183
|
: {
|
|
183
|
-
id: proverId,
|
|
184
|
-
publisher: publisherKeys
|
|
184
|
+
id: config.proverId,
|
|
185
|
+
publisher: publisherKeys,
|
|
185
186
|
},
|
|
186
187
|
remoteSigner: undefined,
|
|
187
188
|
validators: undefined,
|
|
@@ -189,7 +190,7 @@ function createKeyStoreFromPublisherKeys(config: ProverNodeConfig) {
|
|
|
189
190
|
return keyStore;
|
|
190
191
|
}
|
|
191
192
|
|
|
192
|
-
export function createKeyStoreForProver(config: ProverNodeConfig) {
|
|
193
|
+
export function createKeyStoreForProver(config: ProverNodeConfig): KeyStore | undefined {
|
|
193
194
|
if (config.web3SignerUrl !== undefined && config.web3SignerUrl.length > 0) {
|
|
194
195
|
return createKeyStoreFromWeb3Signer(config);
|
|
195
196
|
}
|
package/src/factory.ts
CHANGED
|
@@ -2,20 +2,17 @@ import { type Archiver, createArchiver } from '@aztec/archiver';
|
|
|
2
2
|
import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
|
|
3
3
|
import { type BlobSinkClientInterface, createBlobSinkClient } from '@aztec/blob-sink/client';
|
|
4
4
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
RollupContract,
|
|
10
|
-
createEthereumChain,
|
|
11
|
-
createL1TxUtilsFromEthSigner,
|
|
12
|
-
} from '@aztec/ethereum';
|
|
5
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
6
|
+
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
7
|
+
import { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
8
|
+
import { PublisherManager } from '@aztec/ethereum/publisher-manager';
|
|
13
9
|
import { pick } from '@aztec/foundation/collection';
|
|
14
10
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
15
11
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
16
12
|
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
17
13
|
import { type KeyStoreConfig, KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
|
|
18
14
|
import { trySnapshotSync } from '@aztec/node-lib/actions';
|
|
15
|
+
import { createL1TxUtilsFromEthSignerWithStore } from '@aztec/node-lib/factories';
|
|
19
16
|
import { NodeRpcTxSource, createP2PClient } from '@aztec/p2p';
|
|
20
17
|
import { type ProverClientConfig, createProverClient } from '@aztec/prover-client';
|
|
21
18
|
import { createAndStartProvingBroker } from '@aztec/prover-client/broker';
|
|
@@ -73,6 +70,8 @@ export async function createProverNode(
|
|
|
73
70
|
}
|
|
74
71
|
}
|
|
75
72
|
|
|
73
|
+
await keyStoreManager?.validateSigners();
|
|
74
|
+
|
|
76
75
|
// Extract the prover signers from the key store and verify that we have one.
|
|
77
76
|
const proverSigners = keyStoreManager?.createProverSigners();
|
|
78
77
|
|
|
@@ -86,6 +85,8 @@ export async function createProverNode(
|
|
|
86
85
|
);
|
|
87
86
|
}
|
|
88
87
|
|
|
88
|
+
log.info(`Creating prover with publishers ${proverSigners.signers.map(signer => signer.address.toString()).join()}`);
|
|
89
|
+
|
|
89
90
|
// Only consider user provided config if it is valid
|
|
90
91
|
const proverIdInUserConfig = config.proverId === undefined || config.proverId.isZero() ? undefined : config.proverId;
|
|
91
92
|
|
|
@@ -133,21 +134,26 @@ export async function createProverNode(
|
|
|
133
134
|
|
|
134
135
|
const l1TxUtils = deps.l1TxUtils
|
|
135
136
|
? [deps.l1TxUtils]
|
|
136
|
-
:
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
: await createL1TxUtilsFromEthSignerWithStore(
|
|
138
|
+
publicClient,
|
|
139
|
+
proverSigners.signers,
|
|
140
|
+
{ ...config, scope: 'prover' },
|
|
141
|
+
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
|
|
142
|
+
);
|
|
139
143
|
|
|
140
144
|
const publisherFactory =
|
|
141
145
|
deps.publisherFactory ??
|
|
142
146
|
new ProverPublisherFactory(config, {
|
|
143
147
|
rollupContract,
|
|
144
|
-
publisherManager: new PublisherManager(l1TxUtils),
|
|
148
|
+
publisherManager: new PublisherManager(l1TxUtils, config),
|
|
145
149
|
telemetry,
|
|
146
150
|
});
|
|
147
151
|
|
|
148
152
|
const proofVerifier = new QueuedIVCVerifier(
|
|
149
153
|
config,
|
|
150
|
-
config.realProofs
|
|
154
|
+
config.realProofs || config.debugForceTxProofVerification
|
|
155
|
+
? await BBCircuitVerifier.new(config)
|
|
156
|
+
: new TestCircuitVerifier(config.proverTestVerificationDelayMs),
|
|
151
157
|
);
|
|
152
158
|
|
|
153
159
|
const p2pClient = await createP2PClient(
|
|
@@ -175,10 +181,12 @@ export async function createProverNode(
|
|
|
175
181
|
'proverNodeMaxPendingJobs',
|
|
176
182
|
'proverNodeMaxParallelBlocksPerEpoch',
|
|
177
183
|
'proverNodePollingIntervalMs',
|
|
184
|
+
'proverNodeEpochProvingDelayMs',
|
|
178
185
|
'txGatheringMaxParallelRequests',
|
|
179
186
|
'txGatheringIntervalMs',
|
|
180
187
|
'txGatheringTimeoutMs',
|
|
181
188
|
'proverNodeFailedEpochStore',
|
|
189
|
+
'proverNodeDisableProofPublish',
|
|
182
190
|
'dataDirectory',
|
|
183
191
|
'l1ChainId',
|
|
184
192
|
'rollupVersion',
|
|
@@ -187,7 +195,7 @@ export async function createProverNode(
|
|
|
187
195
|
|
|
188
196
|
const epochMonitor = await EpochMonitor.create(
|
|
189
197
|
archiver,
|
|
190
|
-
{ pollingIntervalMs: config.proverNodePollingIntervalMs },
|
|
198
|
+
{ pollingIntervalMs: config.proverNodePollingIntervalMs, provingDelayMs: config.proverNodeEpochProvingDelayMs },
|
|
191
199
|
telemetry,
|
|
192
200
|
);
|
|
193
201
|
|
|
@@ -1,49 +1,55 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
3
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
|
-
import { CommitteeAttestation
|
|
4
|
+
import { CommitteeAttestation } from '@aztec/stdlib/block';
|
|
5
|
+
import { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
4
6
|
import { BlockHeader, Tx } from '@aztec/stdlib/tx';
|
|
5
7
|
|
|
6
8
|
/** All data from an epoch used in proving. */
|
|
7
9
|
export type EpochProvingJobData = {
|
|
8
|
-
epochNumber:
|
|
9
|
-
|
|
10
|
+
epochNumber: EpochNumber;
|
|
11
|
+
checkpoints: Checkpoint[];
|
|
10
12
|
txs: Map<string, Tx>;
|
|
11
|
-
l1ToL2Messages: Record<
|
|
13
|
+
l1ToL2Messages: Record<CheckpointNumber, Fr[]>;
|
|
12
14
|
previousBlockHeader: BlockHeader;
|
|
13
15
|
attestations: CommitteeAttestation[];
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
export function validateEpochProvingJobData(data: EpochProvingJobData) {
|
|
17
|
-
if (data.
|
|
19
|
+
if (data.checkpoints.length === 0) {
|
|
20
|
+
throw new Error('No checkpoints to prove');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const firstBlockNumber = data.checkpoints[0].blocks[0].number;
|
|
24
|
+
const previousBlockNumber = data.previousBlockHeader.getBlockNumber();
|
|
25
|
+
if (previousBlockNumber + 1 !== firstBlockNumber) {
|
|
18
26
|
throw new Error(
|
|
19
|
-
`Initial block number ${
|
|
20
|
-
data.blocks[0].number
|
|
21
|
-
} does not match previous block header ${data.previousBlockHeader.getBlockNumber()}`,
|
|
27
|
+
`Initial block number ${firstBlockNumber} does not match previous block header ${previousBlockNumber}`,
|
|
22
28
|
);
|
|
23
29
|
}
|
|
24
30
|
|
|
25
|
-
for (const
|
|
26
|
-
if (!(
|
|
27
|
-
throw new Error(`Missing L1 to L2 messages for
|
|
31
|
+
for (const checkpoint of data.checkpoints) {
|
|
32
|
+
if (!(checkpoint.number in data.l1ToL2Messages)) {
|
|
33
|
+
throw new Error(`Missing L1 to L2 messages for checkpoint number ${checkpoint.number}`);
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
export function serializeEpochProvingJobData(data: EpochProvingJobData): Buffer {
|
|
33
|
-
const
|
|
39
|
+
const checkpoints = data.checkpoints.map(checkpoint => checkpoint.toBuffer());
|
|
34
40
|
const txs = Array.from(data.txs.values()).map(tx => tx.toBuffer());
|
|
35
|
-
const l1ToL2Messages = Object.entries(data.l1ToL2Messages).map(([
|
|
36
|
-
Number(
|
|
41
|
+
const l1ToL2Messages = Object.entries(data.l1ToL2Messages).map(([checkpointNumber, messages]) => [
|
|
42
|
+
Number(checkpointNumber),
|
|
37
43
|
messages.length,
|
|
38
44
|
...messages,
|
|
39
45
|
]);
|
|
40
46
|
const attestations = data.attestations.map(attestation => attestation.toBuffer());
|
|
41
47
|
|
|
42
48
|
return serializeToBuffer(
|
|
43
|
-
|
|
49
|
+
data.epochNumber,
|
|
44
50
|
data.previousBlockHeader,
|
|
45
|
-
|
|
46
|
-
...
|
|
51
|
+
checkpoints.length,
|
|
52
|
+
...checkpoints,
|
|
47
53
|
txs.length,
|
|
48
54
|
...txs,
|
|
49
55
|
l1ToL2Messages.length,
|
|
@@ -55,22 +61,22 @@ export function serializeEpochProvingJobData(data: EpochProvingJobData): Buffer
|
|
|
55
61
|
|
|
56
62
|
export function deserializeEpochProvingJobData(buf: Buffer): EpochProvingJobData {
|
|
57
63
|
const reader = BufferReader.asReader(buf);
|
|
58
|
-
const epochNumber =
|
|
64
|
+
const epochNumber = EpochNumber(reader.readNumber());
|
|
59
65
|
const previousBlockHeader = reader.readObject(BlockHeader);
|
|
60
|
-
const
|
|
66
|
+
const checkpoints = reader.readVector(Checkpoint);
|
|
61
67
|
const txArray = reader.readVector(Tx);
|
|
62
68
|
|
|
63
|
-
const
|
|
69
|
+
const l1ToL2MessageCheckpointCount = reader.readNumber();
|
|
64
70
|
const l1ToL2Messages: Record<number, Fr[]> = {};
|
|
65
|
-
for (let i = 0; i <
|
|
66
|
-
const
|
|
71
|
+
for (let i = 0; i < l1ToL2MessageCheckpointCount; i++) {
|
|
72
|
+
const checkpointNumber = CheckpointNumber(reader.readNumber());
|
|
67
73
|
const messages = reader.readVector(Fr);
|
|
68
|
-
l1ToL2Messages[
|
|
74
|
+
l1ToL2Messages[checkpointNumber] = messages;
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
const attestations = reader.readVector(CommitteeAttestation);
|
|
72
78
|
|
|
73
79
|
const txs = new Map<string, Tx>(txArray.map(tx => [tx.getTxHash().toString(), tx]));
|
|
74
80
|
|
|
75
|
-
return { epochNumber, previousBlockHeader,
|
|
81
|
+
return { epochNumber, previousBlockHeader, checkpoints, txs, l1ToL2Messages, attestations };
|
|
76
82
|
}
|