@lodestar/beacon-node 1.50.0-dev.040a952dd7 → 1.50.0-dev.199b9d3a1f
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/lib/chain/archiveStore/archiveStore.js +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +7 -5
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
- package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +1 -1
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +1 -1
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +1 -2
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +4 -5
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +0 -18
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/options.d.ts +1 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +1 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +0 -2
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +4 -10
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +1 -5
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +54 -64
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/metrics/metrics.d.ts +3 -7
- package/lib/metrics/metrics.d.ts.map +1 -1
- package/lib/metrics/metrics.js +4 -4
- package/lib/metrics/metrics.js.map +1 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +3 -25
- package/lib/node/nodejs.js.map +1 -1
- package/package.json +15 -15
- package/src/chain/archiveStore/archiveStore.ts +1 -1
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +7 -5
- package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
- package/src/chain/archiveStore/historicalState/types.ts +2 -2
- package/src/chain/archiveStore/historicalState/worker.ts +2 -1
- package/src/chain/archiveStore/interface.ts +1 -1
- package/src/chain/blocks/verifyBlock.ts +0 -1
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +3 -6
- package/src/chain/chain.ts +0 -21
- package/src/chain/options.ts +2 -2
- package/src/chain/produceBlock/computeNewStateRoot.ts +1 -1
- package/src/chain/regen/regen.ts +4 -12
- package/src/chain/validatorMonitor.ts +57 -75
- package/src/metrics/metrics.ts +6 -21
- package/src/node/nodejs.ts +3 -31
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ChainSafe/lodestar/issues"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.50.0-dev.
|
|
14
|
+
"version": "1.50.0-dev.199b9d3a1f",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -127,17 +127,17 @@
|
|
|
127
127
|
"@libp2p/prometheus-metrics": "^5.0.28",
|
|
128
128
|
"@libp2p/tcp": "^11.0.27",
|
|
129
129
|
"@libp2p/utils": "^7.4.0",
|
|
130
|
-
"@lodestar/api": "^1.50.0-dev.
|
|
131
|
-
"@lodestar/config": "^1.50.0-dev.
|
|
132
|
-
"@lodestar/db": "^1.50.0-dev.
|
|
133
|
-
"@lodestar/fork-choice": "^1.50.0-dev.
|
|
134
|
-
"@lodestar/logger": "^1.50.0-dev.
|
|
135
|
-
"@lodestar/params": "^1.50.0-dev.
|
|
136
|
-
"@lodestar/reqresp": "^1.50.0-dev.
|
|
137
|
-
"@lodestar/state-transition": "^1.50.0-dev.
|
|
138
|
-
"@lodestar/types": "^1.50.0-dev.
|
|
139
|
-
"@lodestar/utils": "^1.50.0-dev.
|
|
140
|
-
"@lodestar/validator": "^1.50.0-dev.
|
|
130
|
+
"@lodestar/api": "^1.50.0-dev.199b9d3a1f",
|
|
131
|
+
"@lodestar/config": "^1.50.0-dev.199b9d3a1f",
|
|
132
|
+
"@lodestar/db": "^1.50.0-dev.199b9d3a1f",
|
|
133
|
+
"@lodestar/fork-choice": "^1.50.0-dev.199b9d3a1f",
|
|
134
|
+
"@lodestar/logger": "^1.50.0-dev.199b9d3a1f",
|
|
135
|
+
"@lodestar/params": "^1.50.0-dev.199b9d3a1f",
|
|
136
|
+
"@lodestar/reqresp": "^1.50.0-dev.199b9d3a1f",
|
|
137
|
+
"@lodestar/state-transition": "^1.50.0-dev.199b9d3a1f",
|
|
138
|
+
"@lodestar/types": "^1.50.0-dev.199b9d3a1f",
|
|
139
|
+
"@lodestar/utils": "^1.50.0-dev.199b9d3a1f",
|
|
140
|
+
"@lodestar/validator": "^1.50.0-dev.199b9d3a1f",
|
|
141
141
|
"@multiformats/multiaddr": "^13.0.1",
|
|
142
142
|
"datastore-core": "^12.0.1",
|
|
143
143
|
"datastore-level": "^13.0.1",
|
|
@@ -158,8 +158,8 @@
|
|
|
158
158
|
"devDependencies": {
|
|
159
159
|
"@libp2p/interface-internal": "^3.1.12",
|
|
160
160
|
"@libp2p/logger": "^6.2.13",
|
|
161
|
-
"@lodestar/spec-test-util": "^1.50.0-dev.
|
|
162
|
-
"@lodestar/test-utils": "^1.50.0-dev.
|
|
161
|
+
"@lodestar/spec-test-util": "^1.50.0-dev.199b9d3a1f",
|
|
162
|
+
"@lodestar/test-utils": "^1.50.0-dev.199b9d3a1f",
|
|
163
163
|
"@types/js-yaml": "^4.0.5",
|
|
164
164
|
"@types/qs": "^6.9.7",
|
|
165
165
|
"@types/tmp": "^0.2.3",
|
|
@@ -174,5 +174,5 @@
|
|
|
174
174
|
"beacon",
|
|
175
175
|
"blockchain"
|
|
176
176
|
],
|
|
177
|
-
"gitHead": "
|
|
177
|
+
"gitHead": "82a54df5956f25254f0d96afe6eae94d93554b5e"
|
|
178
178
|
}
|
|
@@ -148,7 +148,7 @@ export class ArchiveStore {
|
|
|
148
148
|
genesisTime: this.chain.clock.genesisTime,
|
|
149
149
|
dbLocation: this.opts.dbName,
|
|
150
150
|
dataColumnDir: this.opts.dataColumnDir,
|
|
151
|
-
|
|
151
|
+
nativeStateView: this.opts.nativeStateView ?? false,
|
|
152
152
|
},
|
|
153
153
|
config: this.chain.config,
|
|
154
154
|
metrics: this.metrics,
|
|
@@ -17,7 +17,7 @@ export async function getNearestState(
|
|
|
17
17
|
slot: number,
|
|
18
18
|
config: BeaconConfig,
|
|
19
19
|
db: IBeaconDb,
|
|
20
|
-
|
|
20
|
+
nativeStateView: boolean
|
|
21
21
|
): Promise<IBeaconStateView> {
|
|
22
22
|
const stateBytesArr = await db.stateArchive.binaries({limit: 1, lte: slot, reverse: true});
|
|
23
23
|
if (!stateBytesArr.length) {
|
|
@@ -25,7 +25,9 @@ export async function getNearestState(
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const stateBytes = stateBytesArr[0];
|
|
28
|
-
return
|
|
28
|
+
return nativeStateView
|
|
29
|
+
? createBeaconStateViewForHistoricalRegen({useNative: true, stateBytes})
|
|
30
|
+
: createBeaconStateViewForHistoricalRegen({useNative: false, config, stateBytes});
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -35,13 +37,13 @@ export async function getHistoricalState(
|
|
|
35
37
|
slot: number,
|
|
36
38
|
config: BeaconConfig,
|
|
37
39
|
db: IBeaconDb,
|
|
38
|
-
|
|
40
|
+
nativeStateView: boolean,
|
|
39
41
|
metrics?: HistoricalStateRegenMetrics
|
|
40
42
|
): Promise<Uint8Array> {
|
|
41
43
|
const regenTimer = metrics?.regenTime.startTimer();
|
|
42
44
|
|
|
43
45
|
const loadStateTimer = metrics?.loadStateTime.startTimer();
|
|
44
|
-
let state = await getNearestState(slot, config, db,
|
|
46
|
+
let state = await getNearestState(slot, config, db, nativeStateView).catch((e) => {
|
|
45
47
|
metrics?.regenErrorCount.inc({reason: RegenErrorType.loadState});
|
|
46
48
|
throw e;
|
|
47
49
|
});
|
|
@@ -52,7 +54,7 @@ export async function getHistoricalState(
|
|
|
52
54
|
for await (const block of db.blockArchive.valuesStream({gt: state.slot, lte: slot})) {
|
|
53
55
|
try {
|
|
54
56
|
state = state.stateTransition(
|
|
55
|
-
|
|
57
|
+
block,
|
|
56
58
|
{
|
|
57
59
|
verifyProposer: false,
|
|
58
60
|
verifySignatures: false,
|
|
@@ -36,7 +36,7 @@ export class HistoricalStateRegen implements HistoricalStateWorkerApi {
|
|
|
36
36
|
dataColumnDir: modules.opts.dataColumnDir,
|
|
37
37
|
metricsEnabled: Boolean(modules.metrics),
|
|
38
38
|
loggerOpts: modules.logger.toOpts(),
|
|
39
|
-
|
|
39
|
+
nativeStateView: modules.opts.nativeStateView,
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
const worker = new Worker(path.join(WORKER_DIR, "worker.js"), {
|
|
@@ -8,7 +8,7 @@ export type HistoricalStateRegenInitModules = {
|
|
|
8
8
|
genesisTime: number;
|
|
9
9
|
dbLocation: string;
|
|
10
10
|
dataColumnDir: string;
|
|
11
|
-
|
|
11
|
+
nativeStateView: boolean;
|
|
12
12
|
};
|
|
13
13
|
config: BeaconConfig;
|
|
14
14
|
logger: LoggerNode;
|
|
@@ -29,7 +29,7 @@ export type HistoricalStateWorkerData = {
|
|
|
29
29
|
dataColumnDir: string;
|
|
30
30
|
metricsEnabled: boolean;
|
|
31
31
|
loggerOpts: LoggerNodeOpts;
|
|
32
|
-
|
|
32
|
+
nativeStateView: boolean;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
export type HistoricalStateWorkerApi = {
|
|
@@ -36,6 +36,7 @@ const abortController = new AbortController();
|
|
|
36
36
|
const metricsRegister = workerData.metricsEnabled ? new RegistryMetricCreator() : null;
|
|
37
37
|
let historicalStateRegenMetrics: HistoricalStateRegenMetrics | undefined;
|
|
38
38
|
let queueMetrics: QueueMetrics | undefined;
|
|
39
|
+
|
|
39
40
|
if (metricsRegister) {
|
|
40
41
|
const closeMetrics = collectNodeJSMetrics(metricsRegister, "lodestar_historical_state_worker_");
|
|
41
42
|
abortController.signal.addEventListener("abort", closeMetrics, {once: true});
|
|
@@ -64,7 +65,7 @@ const api: HistoricalStateWorkerApi = {
|
|
|
64
65
|
historicalStateRegenMetrics?.regenRequestCount.inc();
|
|
65
66
|
|
|
66
67
|
const stateBytes = await queue.push<Uint8Array>(() =>
|
|
67
|
-
getHistoricalState(slot, config, db, workerData.
|
|
68
|
+
getHistoricalState(slot, config, db, workerData.nativeStateView, historicalStateRegenMetrics)
|
|
68
69
|
);
|
|
69
70
|
const result = Transfer(stateBytes, [stateBytes.buffer]) as unknown as Uint8Array;
|
|
70
71
|
|
|
@@ -188,7 +188,6 @@ export async function verifyBlocksInEpoch(
|
|
|
188
188
|
blockInputs,
|
|
189
189
|
// hack availability for state transition eval as availability is separately determined
|
|
190
190
|
blocks.map(() => DataAvailabilityStatus.Available),
|
|
191
|
-
this.serializedCache,
|
|
192
191
|
this.logger,
|
|
193
192
|
this.metrics,
|
|
194
193
|
this.validatorMonitor,
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
import {ErrorAborted, Logger, byteArrayEquals} from "@lodestar/utils";
|
|
8
8
|
import {Metrics} from "../../metrics/index.js";
|
|
9
9
|
import {nextEventLoop} from "../../util/eventLoop.js";
|
|
10
|
-
import {SerializedCache} from "../../util/serializedCache.js";
|
|
11
10
|
import {BlockError, BlockErrorCode} from "../errors/index.js";
|
|
12
11
|
import {BlockProcessOpts} from "../options.js";
|
|
13
12
|
import {ValidatorMonitor} from "../validatorMonitor.js";
|
|
@@ -26,7 +25,6 @@ export async function verifyBlocksStateTransitionOnly(
|
|
|
26
25
|
preState0: IBeaconStateView,
|
|
27
26
|
blocks: IBlockInput[],
|
|
28
27
|
dataAvailabilityStatuses: DataAvailabilityStatus[],
|
|
29
|
-
serializedCache: SerializedCache,
|
|
30
28
|
logger: Logger,
|
|
31
29
|
metrics: Metrics | null,
|
|
32
30
|
validatorMonitor: ValidatorMonitor | null,
|
|
@@ -39,8 +37,7 @@ export async function verifyBlocksStateTransitionOnly(
|
|
|
39
37
|
|
|
40
38
|
for (let i = 0; i < blocks.length; i++) {
|
|
41
39
|
const {validProposerSignature, validSignatures} = opts;
|
|
42
|
-
const
|
|
43
|
-
const block = blockInput.getBlock();
|
|
40
|
+
const block = blocks[i].getBlock();
|
|
44
41
|
const preState = i === 0 ? preState0 : postStates[i - 1];
|
|
45
42
|
const dataAvailabilityStatus = dataAvailabilityStatuses[i];
|
|
46
43
|
|
|
@@ -50,7 +47,7 @@ export async function verifyBlocksStateTransitionOnly(
|
|
|
50
47
|
let postState: IBeaconStateView;
|
|
51
48
|
try {
|
|
52
49
|
postState = preState.stateTransition(
|
|
53
|
-
|
|
50
|
+
block,
|
|
54
51
|
{
|
|
55
52
|
// NOTE: Assume valid for now while sending payload to execution engine in parallel
|
|
56
53
|
// Latter verifyBlocksInEpoch() will make sure that payload is indeed valid
|
|
@@ -63,7 +60,7 @@ export async function verifyBlocksStateTransitionOnly(
|
|
|
63
60
|
verifySignatures: !useBlsBatchVerify && !validSignatures,
|
|
64
61
|
dontTransferCache: false,
|
|
65
62
|
},
|
|
66
|
-
{metrics
|
|
63
|
+
{metrics, validatorMonitor}
|
|
67
64
|
);
|
|
68
65
|
} catch (e) {
|
|
69
66
|
throw new BlockError(block, {
|
package/src/chain/chain.ts
CHANGED
|
@@ -432,7 +432,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
432
432
|
blockStateCache,
|
|
433
433
|
checkpointStateCache,
|
|
434
434
|
seenBlockInputCache: this.seenBlockInputCache,
|
|
435
|
-
serializedCache: this.serializedCache,
|
|
436
435
|
db,
|
|
437
436
|
metrics,
|
|
438
437
|
validatorMonitor,
|
|
@@ -703,26 +702,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
703
702
|
stateRoot: RootHex,
|
|
704
703
|
opts?: StateGetOpts
|
|
705
704
|
): Promise<{state: IBeaconStateView | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
|
|
706
|
-
const finalizedBlock = this.forkChoice.getFinalizedBlock();
|
|
707
|
-
const finalizedCheckpoint = this.forkChoice.getFinalizedCheckpoint();
|
|
708
|
-
// Checkpoint state only equals the block post-state if the block is at the epoch start slot
|
|
709
|
-
if (
|
|
710
|
-
finalizedBlock.stateRoot === stateRoot &&
|
|
711
|
-
finalizedBlock.slot === computeStartSlotAtEpoch(finalizedCheckpoint.epoch)
|
|
712
|
-
) {
|
|
713
|
-
const state = this.regen.getCheckpointStateSync({
|
|
714
|
-
epoch: finalizedCheckpoint.epoch,
|
|
715
|
-
rootHex: finalizedCheckpoint.rootHex,
|
|
716
|
-
});
|
|
717
|
-
if (state) {
|
|
718
|
-
return {
|
|
719
|
-
state,
|
|
720
|
-
executionOptimistic: isOptimisticBlock(finalizedBlock),
|
|
721
|
-
finalized: finalizedCheckpoint.epoch !== GENESIS_EPOCH,
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
|
|
726
705
|
if (opts?.allowRegen) {
|
|
727
706
|
const state = await this.regen.getState(stateRoot, RegenCaller.restApi);
|
|
728
707
|
const block = this.forkChoice.getBlockDefaultStatus(
|
package/src/chain/options.ts
CHANGED
|
@@ -52,7 +52,7 @@ export type IChainOptions = BlockProcessOpts &
|
|
|
52
52
|
minSameMessageSignatureSetsToBatch: number;
|
|
53
53
|
archiveDateEpochs?: number;
|
|
54
54
|
nHistoricalStatesFileDataStore?: boolean;
|
|
55
|
-
|
|
55
|
+
nativeStateView?: boolean;
|
|
56
56
|
/** Builder circuit breaker fault inspection window in slots */
|
|
57
57
|
faultInspectionWindow?: number;
|
|
58
58
|
/** Canonical EMPTY blocks allowed per `faultInspectionWindow` observed blocks */
|
|
@@ -131,7 +131,7 @@ export const defaultChainOptions: IChainOptions = {
|
|
|
131
131
|
// - users can prune the persisted checkpoint state files manually to save disc space
|
|
132
132
|
// - it helps debug easier when network is unfinalized
|
|
133
133
|
nHistoricalStatesFileDataStore: true,
|
|
134
|
-
|
|
134
|
+
nativeStateView: false,
|
|
135
135
|
maxBlockStates: DEFAULT_MAX_BLOCK_STATES,
|
|
136
136
|
maxCPStateEpochsInMemory: DEFAULT_MAX_CP_STATE_EPOCHS_IN_MEMORY,
|
|
137
137
|
maxCPStateEpochsOnDisk: DEFAULT_MAX_CP_STATE_ON_DISK,
|
|
@@ -16,7 +16,7 @@ export function computeNewStateRoot(
|
|
|
16
16
|
const signedBlock = {message: block, signature: EMPTY_SIGNATURE};
|
|
17
17
|
const {newStateRoot, proposerReward, postState, hashTreeRootTime} = state.computeNewStateRoot(
|
|
18
18
|
{block: signedBlock},
|
|
19
|
-
{metrics
|
|
19
|
+
{metrics}
|
|
20
20
|
);
|
|
21
21
|
|
|
22
22
|
metrics?.stateHashTreeRootTime.observe({source: StateHashTreeRootSource.computeNewStateRoot}, hashTreeRootTime);
|
package/src/chain/regen/regen.ts
CHANGED
|
@@ -14,7 +14,6 @@ import {Logger, fromHex, toRootHex} from "@lodestar/utils";
|
|
|
14
14
|
import {IBeaconDb} from "../../db/index.js";
|
|
15
15
|
import {Metrics} from "../../metrics/index.js";
|
|
16
16
|
import {nextEventLoop} from "../../util/eventLoop.js";
|
|
17
|
-
import {SerializedCache} from "../../util/serializedCache.js";
|
|
18
17
|
import {getCheckpointFromState} from "../blocks/utils/checkpoint.js";
|
|
19
18
|
import {ChainEvent, ChainEventEmitter} from "../emitter.js";
|
|
20
19
|
import {SeenBlockInput} from "../seenCache/seenGossipBlockInput.js";
|
|
@@ -29,7 +28,6 @@ export type RegenModules = {
|
|
|
29
28
|
blockStateCache: BlockStateCache;
|
|
30
29
|
checkpointStateCache: CheckpointStateCache;
|
|
31
30
|
seenBlockInputCache: SeenBlockInput;
|
|
32
|
-
serializedCache: SerializedCache;
|
|
33
31
|
config: ChainForkConfig;
|
|
34
32
|
emitter: ChainEventEmitter;
|
|
35
33
|
logger: Logger;
|
|
@@ -237,7 +235,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
237
235
|
// We are only running the state transition to get a specific state's data.
|
|
238
236
|
// stateTransition() does the clone() inside, transfer cache to make the regen faster
|
|
239
237
|
state = state.stateTransition(
|
|
240
|
-
|
|
238
|
+
block,
|
|
241
239
|
{
|
|
242
240
|
// Replay previously imported blocks, assume valid and available
|
|
243
241
|
executionPayloadStatus: ExecutionPayloadStatus.valid,
|
|
@@ -247,7 +245,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
247
245
|
verifySignatures: false,
|
|
248
246
|
dontTransferCache: false,
|
|
249
247
|
},
|
|
250
|
-
|
|
248
|
+
this.modules
|
|
251
249
|
);
|
|
252
250
|
|
|
253
251
|
const hashTreeRootTimer = this.modules.metrics?.stateHashTreeRootTime.startTimer({
|
|
@@ -318,10 +316,7 @@ async function processSlotsByCheckpoint(
|
|
|
318
316
|
): Promise<IBeaconStateView> {
|
|
319
317
|
let postState = await processSlotsToNearestCheckpoint(modules, preState, slot, regenCaller, opts);
|
|
320
318
|
if (postState.slot < slot) {
|
|
321
|
-
postState = postState.processSlots(slot, opts,
|
|
322
|
-
metrics: modules.metrics?.stateTransition,
|
|
323
|
-
validatorMonitor: modules.validatorMonitor,
|
|
324
|
-
});
|
|
319
|
+
postState = postState.processSlots(slot, opts, modules);
|
|
325
320
|
}
|
|
326
321
|
return postState;
|
|
327
322
|
}
|
|
@@ -366,10 +361,7 @@ export async function processSlotsToNearestCheckpoint(
|
|
|
366
361
|
caller: regenCaller,
|
|
367
362
|
});
|
|
368
363
|
// processSlots calls .clone() before mutating
|
|
369
|
-
postState = postState.processSlots(nextEpochSlot, opts,
|
|
370
|
-
metrics: metrics?.stateTransition,
|
|
371
|
-
validatorMonitor: modules.validatorMonitor,
|
|
372
|
-
});
|
|
364
|
+
postState = postState.processSlots(nextEpochSlot, opts, modules);
|
|
373
365
|
metrics?.epochTransitionByCaller.inc({caller: regenCaller});
|
|
374
366
|
|
|
375
367
|
// this is usually added when we prepare for next slot or validate gossip block
|
|
@@ -123,11 +123,6 @@ export type ValidatorMonitorOpts = {
|
|
|
123
123
|
validatorMonitorLogs?: boolean;
|
|
124
124
|
};
|
|
125
125
|
|
|
126
|
-
export type NativeValidatorMonitor = {
|
|
127
|
-
registerLocalValidator(index: ValidatorIndex): void;
|
|
128
|
-
unregisterLocalValidator(index: ValidatorIndex): void;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
126
|
export const defaultValidatorMonitorOpts: ValidatorMonitorOpts = {
|
|
132
127
|
validatorMonitorLogs: false,
|
|
133
128
|
};
|
|
@@ -301,8 +296,7 @@ export function createValidatorMonitor(
|
|
|
301
296
|
config: ChainForkConfig,
|
|
302
297
|
genesisTime: number,
|
|
303
298
|
logger: Logger,
|
|
304
|
-
opts: ValidatorMonitorOpts
|
|
305
|
-
nativeValidatorMonitor: NativeValidatorMonitor | null = null
|
|
299
|
+
opts: ValidatorMonitorOpts
|
|
306
300
|
): ValidatorMonitor {
|
|
307
301
|
const logLevel = opts.validatorMonitorLogs ? LogLevel.info : LogLevel.debug;
|
|
308
302
|
const log: LogHandler = (message: string, context?: LogData) => {
|
|
@@ -333,23 +327,18 @@ export function createValidatorMonitor(
|
|
|
333
327
|
}));
|
|
334
328
|
|
|
335
329
|
let lastRegisteredStatusEpoch = -1;
|
|
336
|
-
let lastAttestationSummaryEpoch = -1;
|
|
337
330
|
|
|
338
331
|
// Track validator additions/removals per epoch for logging
|
|
339
332
|
const addedValidatorsInEpoch: Set<ValidatorIndex> = new Set();
|
|
340
333
|
const removedValidatorsInEpoch: Set<ValidatorIndex> = new Set();
|
|
341
334
|
|
|
342
|
-
const
|
|
343
|
-
const validatorMonitorMetrics = metricsRegister
|
|
344
|
-
? createValidatorMonitorMetrics(metricsRegister, shouldRegisterStateDerivedMetrics)
|
|
345
|
-
: null;
|
|
335
|
+
const validatorMonitorMetrics = metricsRegister ? createValidatorMonitorMetrics(metricsRegister) : null;
|
|
346
336
|
|
|
347
337
|
const validatorMonitor: ValidatorMonitor = {
|
|
348
338
|
registerLocalValidator(index) {
|
|
349
339
|
const isNewValidator = !validators.has(index);
|
|
350
340
|
validators.getOrDefault(index).lastRegisteredTimeMs = Date.now();
|
|
351
341
|
if (isNewValidator) {
|
|
352
|
-
nativeValidatorMonitor?.registerLocalValidator(index);
|
|
353
342
|
addedValidatorsInEpoch.add(index);
|
|
354
343
|
}
|
|
355
344
|
},
|
|
@@ -377,7 +366,7 @@ export function createValidatorMonitor(
|
|
|
377
366
|
// Track total balance instead of per-validator balance to reduce metric cardinality
|
|
378
367
|
let totalBalance = 0;
|
|
379
368
|
|
|
380
|
-
for (const index of validators.
|
|
369
|
+
for (const [index, monitoredValidator] of validators.entries()) {
|
|
381
370
|
// We subtract two from the state of the epoch that generated these summaries.
|
|
382
371
|
//
|
|
383
372
|
// - One to account for it being the previous epoch.
|
|
@@ -391,29 +380,68 @@ export function createValidatorMonitor(
|
|
|
391
380
|
);
|
|
392
381
|
|
|
393
382
|
if (summary.isPrevSourceAttester) {
|
|
394
|
-
validatorMonitorMetrics?.prevEpochOnChainSourceAttesterHit
|
|
383
|
+
validatorMonitorMetrics?.prevEpochOnChainSourceAttesterHit.inc();
|
|
395
384
|
} else {
|
|
396
|
-
validatorMonitorMetrics?.prevEpochOnChainSourceAttesterMiss
|
|
385
|
+
validatorMonitorMetrics?.prevEpochOnChainSourceAttesterMiss.inc();
|
|
397
386
|
}
|
|
398
387
|
if (summary.isPrevHeadAttester) {
|
|
399
|
-
validatorMonitorMetrics?.prevEpochOnChainHeadAttesterHit
|
|
388
|
+
validatorMonitorMetrics?.prevEpochOnChainHeadAttesterHit.inc();
|
|
400
389
|
} else {
|
|
401
|
-
validatorMonitorMetrics?.prevEpochOnChainHeadAttesterMiss
|
|
390
|
+
validatorMonitorMetrics?.prevEpochOnChainHeadAttesterMiss.inc();
|
|
402
391
|
}
|
|
403
392
|
if (summary.isPrevTargetAttester) {
|
|
404
|
-
validatorMonitorMetrics?.prevEpochOnChainTargetAttesterHit
|
|
393
|
+
validatorMonitorMetrics?.prevEpochOnChainTargetAttesterHit.inc();
|
|
405
394
|
} else {
|
|
406
|
-
validatorMonitorMetrics?.prevEpochOnChainTargetAttesterMiss
|
|
395
|
+
validatorMonitorMetrics?.prevEpochOnChainTargetAttesterMiss.inc();
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const prevEpochSummary = monitoredValidator.summaries.get(previousEpoch);
|
|
399
|
+
const attestationCorrectHead = prevEpochSummary?.attestationCorrectHead;
|
|
400
|
+
if (attestationCorrectHead !== null && attestationCorrectHead !== undefined) {
|
|
401
|
+
if (attestationCorrectHead) {
|
|
402
|
+
validatorMonitorMetrics?.prevOnChainAttesterCorrectHead.inc();
|
|
403
|
+
} else {
|
|
404
|
+
validatorMonitorMetrics?.prevOnChainAttesterIncorrectHead.inc();
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const attestationMinBlockInclusionDistance = prevEpochSummary?.attestationMinBlockInclusionDistance;
|
|
409
|
+
const inclusionDistance =
|
|
410
|
+
attestationMinBlockInclusionDistance != null && attestationMinBlockInclusionDistance > 0
|
|
411
|
+
? // altair, attestation is not missed
|
|
412
|
+
attestationMinBlockInclusionDistance
|
|
413
|
+
: summary.inclusionDistance
|
|
414
|
+
? // phase0, this is from the state transition
|
|
415
|
+
summary.inclusionDistance
|
|
416
|
+
: null;
|
|
417
|
+
|
|
418
|
+
if (inclusionDistance !== null) {
|
|
419
|
+
validatorMonitorMetrics?.prevEpochOnChainInclusionDistance.observe(inclusionDistance);
|
|
420
|
+
validatorMonitorMetrics?.prevEpochOnChainAttesterHit.inc();
|
|
421
|
+
} else {
|
|
422
|
+
validatorMonitorMetrics?.prevEpochOnChainAttesterMiss.inc();
|
|
407
423
|
}
|
|
408
424
|
|
|
409
425
|
const balance = balances?.[index];
|
|
410
426
|
if (balance !== undefined) {
|
|
411
427
|
totalBalance += balance;
|
|
412
428
|
}
|
|
429
|
+
|
|
430
|
+
if (!summary.isPrevSourceAttester || !summary.isPrevTargetAttester || !summary.isPrevHeadAttester) {
|
|
431
|
+
log("Failed attestation in previous epoch", {
|
|
432
|
+
validator: index,
|
|
433
|
+
prevEpoch: currentEpoch - 1,
|
|
434
|
+
isPrevSourceAttester: summary.isPrevSourceAttester,
|
|
435
|
+
isPrevHeadAttester: summary.isPrevHeadAttester,
|
|
436
|
+
isPrevTargetAttester: summary.isPrevTargetAttester,
|
|
437
|
+
// inclusionDistance is not available in summary since altair
|
|
438
|
+
inclusionDistance,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
413
441
|
}
|
|
414
442
|
|
|
415
443
|
if (balances !== undefined) {
|
|
416
|
-
validatorMonitorMetrics?.prevEpochOnChainBalance
|
|
444
|
+
validatorMonitorMetrics?.prevEpochOnChainBalance.set(totalBalance);
|
|
417
445
|
}
|
|
418
446
|
},
|
|
419
447
|
|
|
@@ -704,7 +732,6 @@ export function createValidatorMonitor(
|
|
|
704
732
|
// Prune validators not seen in a while
|
|
705
733
|
for (const [index, validator] of validators.entries()) {
|
|
706
734
|
if (Date.now() - validator.lastRegisteredTimeMs > retainRegisteredValidatorsMs) {
|
|
707
|
-
nativeValidatorMonitor?.unregisterLocalValidator(index);
|
|
708
735
|
validators.delete(index);
|
|
709
736
|
removedValidatorsInEpoch.add(index);
|
|
710
737
|
}
|
|
@@ -740,38 +767,6 @@ export function createValidatorMonitor(
|
|
|
740
767
|
return;
|
|
741
768
|
}
|
|
742
769
|
|
|
743
|
-
// On-chain attestation summary of prevEpoch. Reads only the epoch summaries filled by
|
|
744
|
-
// registerAttestationInBlock(), so it works with both TS and native state transition.
|
|
745
|
-
if (prevEpoch > lastAttestationSummaryEpoch) {
|
|
746
|
-
lastAttestationSummaryEpoch = prevEpoch;
|
|
747
|
-
|
|
748
|
-
for (const monitoredValidator of validators.values()) {
|
|
749
|
-
const prevEpochSummary = monitoredValidator.summaries.get(prevEpoch);
|
|
750
|
-
const attestationCorrectHead = prevEpochSummary?.attestationCorrectHead;
|
|
751
|
-
if (attestationCorrectHead !== null && attestationCorrectHead !== undefined) {
|
|
752
|
-
if (attestationCorrectHead) {
|
|
753
|
-
validatorMonitorMetrics?.prevOnChainAttesterCorrectHead.inc();
|
|
754
|
-
} else {
|
|
755
|
-
validatorMonitorMetrics?.prevOnChainAttesterIncorrectHead.inc();
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
const attestationMinBlockInclusionDistance = prevEpochSummary?.attestationMinBlockInclusionDistance;
|
|
760
|
-
const inclusionDistance =
|
|
761
|
-
attestationMinBlockInclusionDistance != null && attestationMinBlockInclusionDistance > 0
|
|
762
|
-
? // altair, attestation is not missed
|
|
763
|
-
attestationMinBlockInclusionDistance
|
|
764
|
-
: null;
|
|
765
|
-
|
|
766
|
-
if (inclusionDistance !== null) {
|
|
767
|
-
validatorMonitorMetrics?.prevEpochOnChainInclusionDistance.observe(inclusionDistance);
|
|
768
|
-
validatorMonitorMetrics?.prevEpochOnChainAttesterHit.inc();
|
|
769
|
-
} else {
|
|
770
|
-
validatorMonitorMetrics?.prevEpochOnChainAttesterMiss.inc();
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
|
|
775
770
|
const rootCache = new RootHexCache(headState);
|
|
776
771
|
|
|
777
772
|
if (isStatePostAltair(headState)) {
|
|
@@ -789,17 +784,6 @@ export function createValidatorMonitor(
|
|
|
789
784
|
epoch: prevEpoch,
|
|
790
785
|
summary,
|
|
791
786
|
});
|
|
792
|
-
|
|
793
|
-
if (!flags.timelySource || !flags.timelyTarget || !flags.timelyHead) {
|
|
794
|
-
log("Failed attestation in previous epoch", {
|
|
795
|
-
validator: index,
|
|
796
|
-
prevEpoch,
|
|
797
|
-
isPrevSourceAttester: flags.timelySource,
|
|
798
|
-
isPrevHeadAttester: flags.timelyHead,
|
|
799
|
-
isPrevTargetAttester: flags.timelyTarget,
|
|
800
|
-
inclusionDistance: validator.summaries.get(prevEpoch)?.attestationMinBlockInclusionDistance ?? null,
|
|
801
|
-
});
|
|
802
|
-
}
|
|
803
787
|
}
|
|
804
788
|
}
|
|
805
789
|
|
|
@@ -1214,9 +1198,7 @@ export class RootHexCache {
|
|
|
1214
1198
|
}
|
|
1215
1199
|
}
|
|
1216
1200
|
|
|
1217
|
-
function createValidatorMonitorMetrics(register: RegistryMetricCreator
|
|
1218
|
-
const stateDerivedRegister = registerStateDerivedMetrics ? register : null;
|
|
1219
|
-
|
|
1201
|
+
function createValidatorMonitorMetrics(register: RegistryMetricCreator) {
|
|
1220
1202
|
return {
|
|
1221
1203
|
validatorsConnected: register.gauge({
|
|
1222
1204
|
name: "validator_monitor_validators",
|
|
@@ -1235,7 +1217,7 @@ function createValidatorMonitorMetrics(register: RegistryMetricCreator, register
|
|
|
1235
1217
|
}),
|
|
1236
1218
|
|
|
1237
1219
|
// Validator Monitor Metrics (per-epoch summaries)
|
|
1238
|
-
prevEpochOnChainBalance:
|
|
1220
|
+
prevEpochOnChainBalance: register.gauge({
|
|
1239
1221
|
name: "validator_monitor_prev_epoch_on_chain_balance",
|
|
1240
1222
|
help: "Total balance of all monitored validators after an epoch",
|
|
1241
1223
|
}),
|
|
@@ -1247,19 +1229,19 @@ function createValidatorMonitorMetrics(register: RegistryMetricCreator, register
|
|
|
1247
1229
|
name: "validator_monitor_prev_epoch_on_chain_attester_miss_total",
|
|
1248
1230
|
help: "Incremented if validator's submitted attestation is not included in any blocks",
|
|
1249
1231
|
}),
|
|
1250
|
-
prevEpochOnChainSourceAttesterHit:
|
|
1232
|
+
prevEpochOnChainSourceAttesterHit: register.gauge({
|
|
1251
1233
|
name: "validator_monitor_prev_epoch_on_chain_source_attester_hit_total",
|
|
1252
1234
|
help: "Incremented if the validator is flagged as a previous epoch source attester during per epoch processing",
|
|
1253
1235
|
}),
|
|
1254
|
-
prevEpochOnChainSourceAttesterMiss:
|
|
1236
|
+
prevEpochOnChainSourceAttesterMiss: register.gauge({
|
|
1255
1237
|
name: "validator_monitor_prev_epoch_on_chain_source_attester_miss_total",
|
|
1256
1238
|
help: "Incremented if the validator is not flagged as a previous epoch source attester during per epoch processing",
|
|
1257
1239
|
}),
|
|
1258
|
-
prevEpochOnChainHeadAttesterHit:
|
|
1240
|
+
prevEpochOnChainHeadAttesterHit: register.gauge({
|
|
1259
1241
|
name: "validator_monitor_prev_epoch_on_chain_head_attester_hit_total",
|
|
1260
1242
|
help: "Incremented if the validator is flagged as a previous epoch head attester during per epoch processing",
|
|
1261
1243
|
}),
|
|
1262
|
-
prevEpochOnChainHeadAttesterMiss:
|
|
1244
|
+
prevEpochOnChainHeadAttesterMiss: register.gauge({
|
|
1263
1245
|
name: "validator_monitor_prev_epoch_on_chain_head_attester_miss_total",
|
|
1264
1246
|
help: "Incremented if the validator is not flagged as a previous epoch head attester during per epoch processing",
|
|
1265
1247
|
}),
|
|
@@ -1271,11 +1253,11 @@ function createValidatorMonitorMetrics(register: RegistryMetricCreator, register
|
|
|
1271
1253
|
name: "validator_monitor_prev_epoch_on_chain_attester_incorrect_head_total",
|
|
1272
1254
|
help: "Total count of times a validator votes incorrect head",
|
|
1273
1255
|
}),
|
|
1274
|
-
prevEpochOnChainTargetAttesterHit:
|
|
1256
|
+
prevEpochOnChainTargetAttesterHit: register.gauge({
|
|
1275
1257
|
name: "validator_monitor_prev_epoch_on_chain_target_attester_hit_total",
|
|
1276
1258
|
help: "Incremented if the validator is flagged as a previous epoch target attester during per epoch processing",
|
|
1277
1259
|
}),
|
|
1278
|
-
prevEpochOnChainTargetAttesterMiss:
|
|
1260
|
+
prevEpochOnChainTargetAttesterMiss: register.gauge({
|
|
1279
1261
|
name: "validator_monitor_prev_epoch_on_chain_target_attester_miss_total",
|
|
1280
1262
|
help: "Incremented if the validator is not flagged as a previous epoch target attester during per epoch processing",
|
|
1281
1263
|
}),
|
package/src/metrics/metrics.ts
CHANGED
|
@@ -9,42 +9,27 @@ import {RegistryMetricCreator} from "./utils/registryMetricCreator.js";
|
|
|
9
9
|
|
|
10
10
|
export type Metrics = BeaconMetrics &
|
|
11
11
|
ForkChoiceMetrics &
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
stateTransition: BeaconStateTransitionMetrics | null;
|
|
15
|
-
register: RegistryMetricCreator;
|
|
16
|
-
close: () => void;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type CreateMetricsOptions = {
|
|
20
|
-
/*
|
|
21
|
-
* Toggle inclusion of state transition metrics.
|
|
22
|
-
*
|
|
23
|
-
* False when native state transition is used, so we
|
|
24
|
-
* can grab metrics from the native implementation instead.
|
|
25
|
-
* */
|
|
26
|
-
includeStateTransitionMetrics?: boolean;
|
|
27
|
-
collectNodeMetrics?: boolean;
|
|
28
|
-
};
|
|
12
|
+
BeaconStateTransitionMetrics &
|
|
13
|
+
LodestarMetrics & {register: RegistryMetricCreator; close: () => void};
|
|
29
14
|
|
|
30
15
|
export function createMetrics(
|
|
31
16
|
opts: MetricsOptions,
|
|
32
17
|
genesisTime: number,
|
|
33
18
|
externalRegistries: Registry[] = [],
|
|
34
|
-
|
|
19
|
+
{collectNodeMetrics = true}: {collectNodeMetrics?: boolean} = {}
|
|
35
20
|
): Metrics {
|
|
36
21
|
const register = new RegistryMetricCreator();
|
|
37
22
|
const beacon = createBeaconMetrics(register);
|
|
38
23
|
const forkChoice = getForkChoiceMetrics(register);
|
|
39
24
|
const lodestar = createLodestarMetrics(register, opts.metadata, genesisTime);
|
|
40
|
-
const stateTransition =
|
|
25
|
+
const stateTransition = getMetrics(register);
|
|
41
26
|
|
|
42
27
|
const onUnhandledRejection = (_error: unknown): void => {
|
|
43
28
|
lodestar.unhandledPromiseRejections.inc();
|
|
44
29
|
};
|
|
45
30
|
process.on("unhandledRejection", onUnhandledRejection);
|
|
46
31
|
|
|
47
|
-
const nodeJsMetricsClose =
|
|
32
|
+
const nodeJsMetricsClose = collectNodeMetrics ? collectNodeJSMetrics(register) : (): void => {};
|
|
48
33
|
const close = (): void => {
|
|
49
34
|
process.removeListener("unhandledRejection", onUnhandledRejection);
|
|
50
35
|
nodeJsMetricsClose();
|
|
@@ -61,7 +46,7 @@ export function createMetrics(
|
|
|
61
46
|
...beacon,
|
|
62
47
|
...forkChoice,
|
|
63
48
|
...lodestar,
|
|
64
|
-
stateTransition,
|
|
49
|
+
...stateTransition,
|
|
65
50
|
register,
|
|
66
51
|
close,
|
|
67
52
|
};
|