@lodestar/beacon-node 1.39.0-dev.c151a164f2 → 1.39.0-dev.ca786a9fc3
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/README.md +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +4 -2
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +2 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/chain.d.ts +8 -9
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +17 -33
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +3 -3
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -7
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/validation/aggregateAndProof.js +9 -0
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +1 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +3 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +1 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/network/peers/discover.d.ts.map +1 -1
- package/lib/network/peers/discover.js.map +1 -1
- package/lib/node/nodejs.d.ts +6 -3
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +3 -1
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/notifier.d.ts.map +1 -1
- package/lib/node/notifier.js +9 -6
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/backfill/verify.d.ts.map +1 -1
- package/lib/sync/backfill/verify.js +1 -1
- package/lib/sync/backfill/verify.js.map +1 -1
- package/package.json +28 -20
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -2
- package/src/chain/blocks/verifyBlocksSignatures.ts +11 -3
- package/src/chain/chain.ts +27 -38
- package/src/chain/forkChoice/index.ts +3 -2
- package/src/chain/interface.ts +4 -6
- package/src/chain/validation/aggregateAndProof.ts +12 -0
- package/src/chain/validation/attesterSlashing.ts +6 -1
- package/src/chain/validation/block.ts +3 -2
- package/src/chain/validation/proposerSlashing.ts +6 -1
- package/src/chain/validation/voluntaryExit.ts +1 -1
- package/src/network/peers/discover.ts +3 -3
- package/src/node/nodejs.ts +9 -2
- package/src/node/notifier.ts +13 -7
- package/src/sync/backfill/verify.ts +1 -2
- package/lib/chain/rewards/attestationsRewards.d.ts +0 -8
- package/lib/chain/rewards/attestationsRewards.d.ts.map +0 -1
- package/lib/chain/rewards/attestationsRewards.js +0 -112
- package/lib/chain/rewards/attestationsRewards.js.map +0 -1
- package/lib/chain/rewards/blockRewards.d.ts +0 -15
- package/lib/chain/rewards/blockRewards.d.ts.map +0 -1
- package/lib/chain/rewards/blockRewards.js +0 -94
- package/lib/chain/rewards/blockRewards.js.map +0 -1
- package/lib/chain/rewards/syncCommitteeRewards.d.ts +0 -7
- package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +0 -1
- package/lib/chain/rewards/syncCommitteeRewards.js +0 -36
- package/lib/chain/rewards/syncCommitteeRewards.js.map +0 -1
- package/src/chain/rewards/attestationsRewards.ts +0 -206
- package/src/chain/rewards/blockRewards.ts +0 -153
- package/src/chain/rewards/syncCommitteeRewards.ts +0 -60
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.39.0-dev.
|
|
14
|
+
"version": "1.39.0-dev.ca786a9fc3",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -88,13 +88,13 @@
|
|
|
88
88
|
"scripts": {
|
|
89
89
|
"clean": "rm -rf lib && rm -f *.tsbuildinfo",
|
|
90
90
|
"build": "tsc -p tsconfig.build.json",
|
|
91
|
-
"build:watch": "
|
|
92
|
-
"build:release": "
|
|
91
|
+
"build:watch": "pnpm run build --watch",
|
|
92
|
+
"build:release": "pnpm clean && pnpm run build",
|
|
93
93
|
"check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"",
|
|
94
94
|
"check-types": "tsc",
|
|
95
95
|
"lint": "biome check src/ test/",
|
|
96
|
-
"lint:fix": "
|
|
97
|
-
"test": "
|
|
96
|
+
"lint:fix": "pnpm run lint --write",
|
|
97
|
+
"test": "pnpm test:unit && pnpm test:e2e",
|
|
98
98
|
"test:unit": "vitest run --project unit --project unit-minimal",
|
|
99
99
|
"test:e2e": "vitest run --project e2e --project e2e-mainnet",
|
|
100
100
|
"test:sim": "vitest run test/sim/**/*.test.ts",
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
"test:spec:general": "vitest run --project spec-minimal test/spec/general/",
|
|
105
105
|
"test:spec:minimal": "vitest run --project spec-minimal test/spec/presets/",
|
|
106
106
|
"test:spec:mainnet": "vitest run --project spec-mainnet test/spec/presets/",
|
|
107
|
-
"test:spec": "
|
|
108
|
-
"check-readme": "
|
|
107
|
+
"test:spec": "pnpm test:spec:bls && pnpm test:spec:general && pnpm test:spec:minimal && pnpm test:spec:mainnet",
|
|
108
|
+
"check-readme": "pnpm exec ts-node ../../scripts/check_readme.ts"
|
|
109
109
|
},
|
|
110
110
|
"dependencies": {
|
|
111
111
|
"@chainsafe/as-sha256": "^1.2.0",
|
|
@@ -134,18 +134,18 @@
|
|
|
134
134
|
"@libp2p/peer-id": "^5.1.0",
|
|
135
135
|
"@libp2p/prometheus-metrics": "^4.3.15",
|
|
136
136
|
"@libp2p/tcp": "^10.1.8",
|
|
137
|
-
"@lodestar/api": "1.39.0-dev.
|
|
138
|
-
"@lodestar/config": "1.39.0-dev.
|
|
139
|
-
"@lodestar/db": "1.39.0-dev.
|
|
140
|
-
"@lodestar/fork-choice": "1.39.0-dev.
|
|
141
|
-
"@lodestar/light-client": "1.39.0-dev.
|
|
142
|
-
"@lodestar/logger": "1.39.0-dev.
|
|
143
|
-
"@lodestar/params": "1.39.0-dev.
|
|
144
|
-
"@lodestar/reqresp": "1.39.0-dev.
|
|
145
|
-
"@lodestar/state-transition": "1.39.0-dev.
|
|
146
|
-
"@lodestar/types": "1.39.0-dev.
|
|
147
|
-
"@lodestar/utils": "1.39.0-dev.
|
|
148
|
-
"@lodestar/validator": "1.39.0-dev.
|
|
137
|
+
"@lodestar/api": "^1.39.0-dev.ca786a9fc3",
|
|
138
|
+
"@lodestar/config": "^1.39.0-dev.ca786a9fc3",
|
|
139
|
+
"@lodestar/db": "^1.39.0-dev.ca786a9fc3",
|
|
140
|
+
"@lodestar/fork-choice": "^1.39.0-dev.ca786a9fc3",
|
|
141
|
+
"@lodestar/light-client": "^1.39.0-dev.ca786a9fc3",
|
|
142
|
+
"@lodestar/logger": "^1.39.0-dev.ca786a9fc3",
|
|
143
|
+
"@lodestar/params": "^1.39.0-dev.ca786a9fc3",
|
|
144
|
+
"@lodestar/reqresp": "^1.39.0-dev.ca786a9fc3",
|
|
145
|
+
"@lodestar/state-transition": "^1.39.0-dev.ca786a9fc3",
|
|
146
|
+
"@lodestar/types": "^1.39.0-dev.ca786a9fc3",
|
|
147
|
+
"@lodestar/utils": "^1.39.0-dev.ca786a9fc3",
|
|
148
|
+
"@lodestar/validator": "^1.39.0-dev.ca786a9fc3",
|
|
149
149
|
"@multiformats/multiaddr": "^12.1.3",
|
|
150
150
|
"datastore-core": "^10.0.2",
|
|
151
151
|
"datastore-fs": "^10.0.6",
|
|
@@ -166,12 +166,20 @@
|
|
|
166
166
|
"xxhash-wasm": "1.0.2"
|
|
167
167
|
},
|
|
168
168
|
"devDependencies": {
|
|
169
|
+
"@chainsafe/swap-or-not-shuffle": "^1.2.1",
|
|
170
|
+
"@libp2p/interface-internal": "^2.3.18",
|
|
171
|
+
"@libp2p/logger": "^5.1.21",
|
|
172
|
+
"@lodestar/spec-test-util": "^1.39.0-dev.ca786a9fc3",
|
|
173
|
+
"@types/js-yaml": "^4.0.5",
|
|
169
174
|
"@types/qs": "^6.9.7",
|
|
170
175
|
"@types/tmp": "^0.2.3",
|
|
171
176
|
"it-drain": "^3.0.3",
|
|
172
177
|
"it-pair": "^2.0.6",
|
|
178
|
+
"js-yaml": "^4.1.0",
|
|
173
179
|
"rewiremock": "^3.14.5",
|
|
174
180
|
"rimraf": "^4.4.1",
|
|
181
|
+
"snappy": "^7.2.2",
|
|
182
|
+
"snappyjs": "^0.7.0",
|
|
175
183
|
"tmp": "^0.2.1"
|
|
176
184
|
},
|
|
177
185
|
"keywords": [
|
|
@@ -180,5 +188,5 @@
|
|
|
180
188
|
"beacon",
|
|
181
189
|
"blockchain"
|
|
182
190
|
],
|
|
183
|
-
"gitHead": "
|
|
191
|
+
"gitHead": "ec0c91055ac75daca7bcebe5ed4b6f85ee1260ce"
|
|
184
192
|
}
|
|
@@ -8,7 +8,12 @@ import {
|
|
|
8
8
|
ProtoBlock,
|
|
9
9
|
} from "@lodestar/fork-choice";
|
|
10
10
|
import {ForkSeq} from "@lodestar/params";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
CachedBeaconStateAllForks,
|
|
13
|
+
isExecutionBlockBodyType,
|
|
14
|
+
isExecutionEnabled,
|
|
15
|
+
isExecutionStateType,
|
|
16
|
+
} from "@lodestar/state-transition";
|
|
12
17
|
import {bellatrix, electra} from "@lodestar/types";
|
|
13
18
|
import {ErrorAborted, Logger, toRootHex} from "@lodestar/utils";
|
|
14
19
|
import {ExecutionPayloadStatus, IExecutionEngine} from "../../execution/engine/interface.js";
|
|
@@ -145,7 +150,9 @@ export async function verifyBlockExecutionPayload(
|
|
|
145
150
|
const block = blockInput.getBlock();
|
|
146
151
|
/** Not null if execution is enabled */
|
|
147
152
|
const executionPayloadEnabled =
|
|
148
|
-
isExecutionStateType(preState0) &&
|
|
153
|
+
isExecutionStateType(preState0) &&
|
|
154
|
+
isExecutionBlockBodyType(block.message.body) &&
|
|
155
|
+
isExecutionEnabled(preState0, block.message)
|
|
149
156
|
? block.message.body.executionPayload
|
|
150
157
|
: null;
|
|
151
158
|
|
|
@@ -28,6 +28,7 @@ export async function verifyBlocksSignatures(
|
|
|
28
28
|
): Promise<{verifySignaturesTime: number}> {
|
|
29
29
|
const isValidPromises: Promise<boolean>[] = [];
|
|
30
30
|
const recvToValLatency = Date.now() / 1000 - (opts.seenTimestampSec ?? Date.now() / 1000);
|
|
31
|
+
const currentSyncCommitteeIndexed = preState0.epochCtx.currentSyncCommitteeIndexed;
|
|
31
32
|
|
|
32
33
|
// Verifies signatures after running state transition, so all SyncCommittee signed roots are known at this point.
|
|
33
34
|
// We must ensure block.slot <= state.slot before running getAllBlockSignatureSets().
|
|
@@ -41,9 +42,16 @@ export async function verifyBlocksSignatures(
|
|
|
41
42
|
: //
|
|
42
43
|
// Verify signatures per block to track which block is invalid
|
|
43
44
|
bls.verifySignatureSets(
|
|
44
|
-
getBlockSignatureSets(
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
getBlockSignatureSets(
|
|
46
|
+
config,
|
|
47
|
+
index2pubkey,
|
|
48
|
+
currentSyncCommitteeIndexed,
|
|
49
|
+
block,
|
|
50
|
+
indexedAttestationsByBlock[i],
|
|
51
|
+
{
|
|
52
|
+
skipProposerSignature: opts.validProposerSignature,
|
|
53
|
+
}
|
|
54
|
+
)
|
|
47
55
|
);
|
|
48
56
|
|
|
49
57
|
// getBlockSignatureSets() takes 45ms in benchmarks for 2022Q2 mainnet blocks (100 sigs). When syncing a 32 blocks
|
package/src/chain/chain.ts
CHANGED
|
@@ -14,13 +14,14 @@ import {
|
|
|
14
14
|
EpochShuffling,
|
|
15
15
|
Index2PubkeyCache,
|
|
16
16
|
computeAnchorCheckpoint,
|
|
17
|
+
computeAttestationsRewards,
|
|
18
|
+
computeBlockRewards,
|
|
17
19
|
computeEndSlotAtEpoch,
|
|
18
20
|
computeEpochAtSlot,
|
|
19
21
|
computeStartSlotAtEpoch,
|
|
20
|
-
|
|
22
|
+
computeSyncCommitteeRewards,
|
|
21
23
|
getEffectiveBalanceIncrementsZeroInactive,
|
|
22
24
|
getEffectiveBalancesFromStateBytes,
|
|
23
|
-
isCachedBeaconState,
|
|
24
25
|
processSlots,
|
|
25
26
|
} from "@lodestar/state-transition";
|
|
26
27
|
import {
|
|
@@ -38,6 +39,7 @@ import {
|
|
|
38
39
|
Wei,
|
|
39
40
|
isBlindedBeaconBlock,
|
|
40
41
|
phase0,
|
|
42
|
+
rewards,
|
|
41
43
|
} from "@lodestar/types";
|
|
42
44
|
import {Logger, fromHex, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toRootHex} from "@lodestar/utils";
|
|
43
45
|
import {ProcessShutdownCallback} from "@lodestar/validator";
|
|
@@ -79,9 +81,6 @@ import {AssembledBlockType, BlockType, ProduceResult} from "./produceBlock/index
|
|
|
79
81
|
import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
|
|
80
82
|
import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
|
|
81
83
|
import {ReprocessController} from "./reprocess.js";
|
|
82
|
-
import {AttestationsRewards, computeAttestationsRewards} from "./rewards/attestationsRewards.js";
|
|
83
|
-
import {BlockRewards, computeBlockRewards} from "./rewards/blockRewards.js";
|
|
84
|
-
import {SyncCommitteeRewards, computeSyncCommitteeRewards} from "./rewards/syncCommitteeRewards.js";
|
|
85
84
|
import {
|
|
86
85
|
SeenAggregators,
|
|
87
86
|
SeenAttesters,
|
|
@@ -204,6 +203,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
204
203
|
{
|
|
205
204
|
privateKey,
|
|
206
205
|
config,
|
|
206
|
+
pubkey2index,
|
|
207
|
+
index2pubkey,
|
|
207
208
|
db,
|
|
208
209
|
dbName,
|
|
209
210
|
dataDir,
|
|
@@ -219,6 +220,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
219
220
|
}: {
|
|
220
221
|
privateKey: PrivateKey;
|
|
221
222
|
config: BeaconConfig;
|
|
223
|
+
pubkey2index: PubkeyIndexMap;
|
|
224
|
+
index2pubkey: Index2PubkeyCache;
|
|
222
225
|
db: IBeaconDb;
|
|
223
226
|
dbName: string;
|
|
224
227
|
dataDir: string;
|
|
@@ -228,7 +231,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
228
231
|
clock?: IClock;
|
|
229
232
|
metrics: Metrics | null;
|
|
230
233
|
validatorMonitor: ValidatorMonitor | null;
|
|
231
|
-
anchorState:
|
|
234
|
+
anchorState: CachedBeaconStateAllForks;
|
|
232
235
|
isAnchorStateFinalized: boolean;
|
|
233
236
|
executionEngine: IExecutionEngine;
|
|
234
237
|
executionBuilder?: IExecutionBuilder;
|
|
@@ -287,39 +290,25 @@ export class BeaconChain implements IBeaconChain {
|
|
|
287
290
|
logger,
|
|
288
291
|
});
|
|
289
292
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
// pubkeys takes ~30 seconds for 350k keys (mainnet 2022Q2).
|
|
293
|
-
// When the BeaconStateCache is created in initializeBeaconStateFromEth1 it may be incorrect. Until we can ensure that
|
|
294
|
-
// it's safe to re-use _ANY_ BeaconStateCache, this option is disabled by default and only used in tests.
|
|
295
|
-
const cachedState =
|
|
296
|
-
isCachedBeaconState(anchorState) && opts.skipCreateStateCacheIfAvailable
|
|
297
|
-
? anchorState
|
|
298
|
-
: createCachedBeaconState(anchorState, {
|
|
299
|
-
config,
|
|
300
|
-
pubkey2index: new PubkeyIndexMap(),
|
|
301
|
-
index2pubkey: [],
|
|
302
|
-
});
|
|
303
|
-
this._earliestAvailableSlot = cachedState.slot;
|
|
304
|
-
|
|
305
|
-
this.shufflingCache = cachedState.epochCtx.shufflingCache = new ShufflingCache(metrics, logger, this.opts, [
|
|
293
|
+
this._earliestAvailableSlot = anchorState.slot;
|
|
294
|
+
this.shufflingCache = anchorState.epochCtx.shufflingCache = new ShufflingCache(metrics, logger, this.opts, [
|
|
306
295
|
{
|
|
307
|
-
shuffling:
|
|
308
|
-
decisionRoot:
|
|
296
|
+
shuffling: anchorState.epochCtx.previousShuffling,
|
|
297
|
+
decisionRoot: anchorState.epochCtx.previousDecisionRoot,
|
|
309
298
|
},
|
|
310
299
|
{
|
|
311
|
-
shuffling:
|
|
312
|
-
decisionRoot:
|
|
300
|
+
shuffling: anchorState.epochCtx.currentShuffling,
|
|
301
|
+
decisionRoot: anchorState.epochCtx.currentDecisionRoot,
|
|
313
302
|
},
|
|
314
303
|
{
|
|
315
|
-
shuffling:
|
|
316
|
-
decisionRoot:
|
|
304
|
+
shuffling: anchorState.epochCtx.nextShuffling,
|
|
305
|
+
decisionRoot: anchorState.epochCtx.nextDecisionRoot,
|
|
317
306
|
},
|
|
318
307
|
]);
|
|
319
308
|
|
|
320
|
-
//
|
|
321
|
-
this.pubkey2index =
|
|
322
|
-
this.index2pubkey =
|
|
309
|
+
// Global cache of validators pubkey/index mapping
|
|
310
|
+
this.pubkey2index = pubkey2index;
|
|
311
|
+
this.index2pubkey = index2pubkey;
|
|
323
312
|
|
|
324
313
|
const fileDataStore = opts.nHistoricalStatesFileDataStore ?? true;
|
|
325
314
|
const blockStateCache = this.opts.nHistoricalStates
|
|
@@ -350,15 +339,15 @@ export class BeaconChain implements IBeaconChain {
|
|
|
350
339
|
}
|
|
351
340
|
|
|
352
341
|
const {checkpoint} = computeAnchorCheckpoint(config, anchorState);
|
|
353
|
-
blockStateCache.add(
|
|
354
|
-
blockStateCache.setHeadState(
|
|
355
|
-
checkpointStateCache.add(checkpoint,
|
|
342
|
+
blockStateCache.add(anchorState);
|
|
343
|
+
blockStateCache.setHeadState(anchorState);
|
|
344
|
+
checkpointStateCache.add(checkpoint, anchorState);
|
|
356
345
|
|
|
357
346
|
const forkChoice = initializeForkChoice(
|
|
358
347
|
config,
|
|
359
348
|
emitter,
|
|
360
349
|
clock.currentSlot,
|
|
361
|
-
|
|
350
|
+
anchorState,
|
|
362
351
|
isAnchorStateFinalized,
|
|
363
352
|
opts,
|
|
364
353
|
this.justifiedBalancesGetter.bind(this),
|
|
@@ -1297,7 +1286,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1297
1286
|
}
|
|
1298
1287
|
}
|
|
1299
1288
|
|
|
1300
|
-
async getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards> {
|
|
1289
|
+
async getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<rewards.BlockRewards> {
|
|
1301
1290
|
let preState = this.regen.getPreStateSync(block);
|
|
1302
1291
|
|
|
1303
1292
|
if (preState === null) {
|
|
@@ -1314,7 +1303,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1314
1303
|
async getAttestationsRewards(
|
|
1315
1304
|
epoch: Epoch,
|
|
1316
1305
|
validatorIds?: (ValidatorIndex | string)[]
|
|
1317
|
-
): Promise<{rewards: AttestationsRewards; executionOptimistic: boolean; finalized: boolean}> {
|
|
1306
|
+
): Promise<{rewards: rewards.AttestationsRewards; executionOptimistic: boolean; finalized: boolean}> {
|
|
1318
1307
|
// We use end slot of (epoch + 1) to ensure we have seen all attestations. On-time or late. Any late attestation beyond this slot is not considered
|
|
1319
1308
|
const slot = computeEndSlotAtEpoch(epoch + 1);
|
|
1320
1309
|
const stateResult = await this.getStateBySlot(slot, {allowRegen: false}); // No regen if state not in cache
|
|
@@ -1340,7 +1329,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1340
1329
|
async getSyncCommitteeRewards(
|
|
1341
1330
|
block: BeaconBlock | BlindedBeaconBlock,
|
|
1342
1331
|
validatorIds?: (ValidatorIndex | string)[]
|
|
1343
|
-
): Promise<SyncCommitteeRewards> {
|
|
1332
|
+
): Promise<rewards.SyncCommitteeRewards> {
|
|
1344
1333
|
let preState = this.regen.getPreStateSync(block);
|
|
1345
1334
|
|
|
1346
1335
|
if (preState === null) {
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
getBlockRootAtSlot,
|
|
19
19
|
getEffectiveBalanceIncrementsZeroInactive,
|
|
20
20
|
isExecutionStateType,
|
|
21
|
+
isMergeTransitionComplete,
|
|
21
22
|
} from "@lodestar/state-transition";
|
|
22
23
|
import {Slot, ssz} from "@lodestar/types";
|
|
23
24
|
import {Logger, toRootHex} from "@lodestar/utils";
|
|
@@ -134,7 +135,7 @@ export function initializeForkChoiceFromFinalizedState(
|
|
|
134
135
|
unrealizedFinalizedEpoch: finalizedCheckpoint.epoch,
|
|
135
136
|
unrealizedFinalizedRoot: toRootHex(finalizedCheckpoint.root),
|
|
136
137
|
|
|
137
|
-
...(isExecutionStateType(state)
|
|
138
|
+
...(isExecutionStateType(state) && isMergeTransitionComplete(state)
|
|
138
139
|
? {
|
|
139
140
|
executionPayloadBlockHash: toRootHex(state.latestExecutionPayloadHeader.blockHash),
|
|
140
141
|
executionPayloadNumber: state.latestExecutionPayloadHeader.blockNumber,
|
|
@@ -215,7 +216,7 @@ export function initializeForkChoiceFromUnfinalizedState(
|
|
|
215
216
|
unrealizedFinalizedEpoch: finalizedCheckpoint.epoch,
|
|
216
217
|
unrealizedFinalizedRoot: toRootHex(finalizedCheckpoint.root),
|
|
217
218
|
|
|
218
|
-
...(isExecutionStateType(unfinalizedState)
|
|
219
|
+
...(isExecutionStateType(unfinalizedState) && isMergeTransitionComplete(unfinalizedState)
|
|
219
220
|
? {
|
|
220
221
|
executionPayloadBlockHash: toRootHex(unfinalizedState.latestExecutionPayloadHeader.blockHash),
|
|
221
222
|
executionPayloadNumber: unfinalizedState.latestExecutionPayloadHeader.blockNumber,
|
package/src/chain/interface.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
altair,
|
|
24
24
|
capella,
|
|
25
25
|
phase0,
|
|
26
|
+
rewards,
|
|
26
27
|
} from "@lodestar/types";
|
|
27
28
|
import {Logger} from "@lodestar/utils";
|
|
28
29
|
import {IExecutionBuilder, IExecutionEngine} from "../execution/index.js";
|
|
@@ -48,9 +49,6 @@ import {IChainOptions} from "./options.js";
|
|
|
48
49
|
import {AssembledBlockType, BlockAttributes, BlockType, ProduceResult} from "./produceBlock/produceBlockBody.js";
|
|
49
50
|
import {IStateRegenerator, RegenCaller} from "./regen/index.js";
|
|
50
51
|
import {ReprocessController} from "./reprocess.js";
|
|
51
|
-
import {AttestationsRewards} from "./rewards/attestationsRewards.js";
|
|
52
|
-
import {BlockRewards} from "./rewards/blockRewards.js";
|
|
53
|
-
import {SyncCommitteeRewards} from "./rewards/syncCommitteeRewards.js";
|
|
54
52
|
import {
|
|
55
53
|
SeenAggregators,
|
|
56
54
|
SeenAttesters,
|
|
@@ -255,15 +253,15 @@ export interface IBeaconChain {
|
|
|
255
253
|
regenCanAcceptWork(): boolean;
|
|
256
254
|
blsThreadPoolCanAcceptWork(): boolean;
|
|
257
255
|
|
|
258
|
-
getBlockRewards(blockRef: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards>;
|
|
256
|
+
getBlockRewards(blockRef: BeaconBlock | BlindedBeaconBlock): Promise<rewards.BlockRewards>;
|
|
259
257
|
getAttestationsRewards(
|
|
260
258
|
epoch: Epoch,
|
|
261
259
|
validatorIds?: (ValidatorIndex | string)[]
|
|
262
|
-
): Promise<{rewards: AttestationsRewards; executionOptimistic: boolean; finalized: boolean}>;
|
|
260
|
+
): Promise<{rewards: rewards.AttestationsRewards; executionOptimistic: boolean; finalized: boolean}>;
|
|
263
261
|
getSyncCommitteeRewards(
|
|
264
262
|
blockRef: BeaconBlock | BlindedBeaconBlock,
|
|
265
263
|
validatorIds?: (ValidatorIndex | string)[]
|
|
266
|
-
): Promise<SyncCommitteeRewards>;
|
|
264
|
+
): Promise<rewards.SyncCommitteeRewards>;
|
|
267
265
|
}
|
|
268
266
|
|
|
269
267
|
export type SSZObjectType =
|
|
@@ -245,6 +245,18 @@ async function validateAggregateAndProof(
|
|
|
245
245
|
});
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
// Same race-condition check as above for seen aggregators
|
|
249
|
+
if (
|
|
250
|
+
!skipValidationKnownAttesters &&
|
|
251
|
+
chain.seenAggregatedAttestations.isKnown(targetEpoch, attIndex, attDataRootHex, aggregationBits)
|
|
252
|
+
) {
|
|
253
|
+
throw new AttestationError(GossipAction.IGNORE, {
|
|
254
|
+
code: AttestationErrorCode.ATTESTERS_ALREADY_KNOWN,
|
|
255
|
+
targetEpoch,
|
|
256
|
+
aggregateRoot: attDataRootHex,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
248
260
|
chain.seenAggregators.add(targetEpoch, aggregatorIndex);
|
|
249
261
|
chain.seenAggregatedAttestations.add(
|
|
250
262
|
targetEpoch,
|
|
@@ -51,7 +51,12 @@ export async function validateAttesterSlashing(
|
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const signatureSets = getAttesterSlashingSignatureSets(
|
|
54
|
+
const signatureSets = getAttesterSlashingSignatureSets(
|
|
55
|
+
chain.config,
|
|
56
|
+
chain.index2pubkey,
|
|
57
|
+
state.slot,
|
|
58
|
+
attesterSlashing
|
|
59
|
+
);
|
|
55
60
|
if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
|
|
56
61
|
throw new AttesterSlashingError(GossipAction.REJECT, {
|
|
57
62
|
code: AttesterSlashingErrorCode.INVALID,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
computeTimeAtSlot,
|
|
7
7
|
getBlockProposerSignatureSet,
|
|
8
8
|
isExecutionBlockBodyType,
|
|
9
|
+
isExecutionEnabled,
|
|
9
10
|
isExecutionStateType,
|
|
10
11
|
} from "@lodestar/state-transition";
|
|
11
12
|
import {SignedBeaconBlock, deneb} from "@lodestar/types";
|
|
@@ -139,7 +140,7 @@ export async function validateGossipBlock(
|
|
|
139
140
|
if (fork === ForkName.bellatrix) {
|
|
140
141
|
if (!isExecutionBlockBodyType(block.body)) throw Error("Not merge block type");
|
|
141
142
|
const executionPayload = block.body.executionPayload;
|
|
142
|
-
if (isExecutionStateType(blockState)) {
|
|
143
|
+
if (isExecutionStateType(blockState) && isExecutionEnabled(blockState, block)) {
|
|
143
144
|
const expectedTimestamp = computeTimeAtSlot(config, blockSlot, chain.genesisTime);
|
|
144
145
|
if (executionPayload.timestamp !== computeTimeAtSlot(config, blockSlot, chain.genesisTime)) {
|
|
145
146
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
@@ -153,7 +154,7 @@ export async function validateGossipBlock(
|
|
|
153
154
|
|
|
154
155
|
// [REJECT] The proposer signature, signed_beacon_block.signature, is valid with respect to the proposer_index pubkey.
|
|
155
156
|
if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blockSlot, blockRoot, signedBlock.signature)) {
|
|
156
|
-
const signatureSet = getBlockProposerSignatureSet(chain.config, chain.index2pubkey,
|
|
157
|
+
const signatureSet = getBlockProposerSignatureSet(chain.config, chain.index2pubkey, signedBlock);
|
|
157
158
|
// Don't batch so verification is not delayed
|
|
158
159
|
if (!(await chain.bls.verifySignatureSets([signatureSet], {verifyOnMainThread: true}))) {
|
|
159
160
|
throw new BlockGossipError(GossipAction.REJECT, {
|
|
@@ -44,7 +44,12 @@ async function validateProposerSlashing(
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const signatureSets = getProposerSlashingSignatureSets(
|
|
47
|
+
const signatureSets = getProposerSlashingSignatureSets(
|
|
48
|
+
chain.config,
|
|
49
|
+
chain.index2pubkey,
|
|
50
|
+
state.slot,
|
|
51
|
+
proposerSlashing
|
|
52
|
+
);
|
|
48
53
|
if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
|
|
49
54
|
throw new ProposerSlashingError(GossipAction.REJECT, {
|
|
50
55
|
code: ProposerSlashingErrorCode.INVALID,
|
|
@@ -59,7 +59,7 @@ async function validateVoluntaryExit(
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
const signatureSet = getVoluntaryExitSignatureSet(chain.config, chain.index2pubkey, state, voluntaryExit);
|
|
62
|
+
const signatureSet = getVoluntaryExitSignatureSet(chain.config, chain.index2pubkey, state.slot, voluntaryExit);
|
|
63
63
|
if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
|
|
64
64
|
throw new VoluntaryExitError(GossipAction.REJECT, {
|
|
65
65
|
code: VoluntaryExitErrorCode.INVALID_SIGNATURE,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {PeerId, PeerInfo, PrivateKey} from "@libp2p/interface";
|
|
1
|
+
import type {PeerId, PeerInfo, PendingDial, PrivateKey} from "@libp2p/interface";
|
|
2
2
|
import {Multiaddr} from "@multiformats/multiaddr";
|
|
3
3
|
import {ENR} from "@chainsafe/enr";
|
|
4
4
|
import {BeaconConfig} from "@lodestar/config";
|
|
@@ -217,7 +217,7 @@ export class PeerDiscovery {
|
|
|
217
217
|
const pendingDials = new Set(
|
|
218
218
|
this.libp2p.services.components.connectionManager
|
|
219
219
|
.getDialQueue()
|
|
220
|
-
.map((pendingDial) => pendingDial.peerId?.toString())
|
|
220
|
+
.map((pendingDial: PendingDial) => pendingDial.peerId?.toString())
|
|
221
221
|
);
|
|
222
222
|
for (const [id, cachedENR] of this.cachedENRs.entries()) {
|
|
223
223
|
if (
|
|
@@ -458,7 +458,7 @@ export class PeerDiscovery {
|
|
|
458
458
|
if (
|
|
459
459
|
this.libp2p.services.components.connectionManager
|
|
460
460
|
.getDialQueue()
|
|
461
|
-
.find((pendingDial) => pendingDial.peerId?.equals(peerId))
|
|
461
|
+
.find((pendingDial: PendingDial) => pendingDial.peerId?.equals(peerId))
|
|
462
462
|
) {
|
|
463
463
|
return DiscoveredPeerStatus.already_dialing;
|
|
464
464
|
}
|
package/src/node/nodejs.ts
CHANGED
|
@@ -2,10 +2,11 @@ import {setMaxListeners} from "node:events";
|
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
3
|
import {Registry} from "prom-client";
|
|
4
4
|
import {hasher} from "@chainsafe/persistent-merkle-tree";
|
|
5
|
+
import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
|
|
5
6
|
import {BeaconApiMethods} from "@lodestar/api/beacon/server";
|
|
6
7
|
import {BeaconConfig} from "@lodestar/config";
|
|
7
8
|
import type {LoggerNode} from "@lodestar/logger/node";
|
|
8
|
-
import {
|
|
9
|
+
import {CachedBeaconStateAllForks, Index2PubkeyCache} from "@lodestar/state-transition";
|
|
9
10
|
import {phase0} from "@lodestar/types";
|
|
10
11
|
import {sleep} from "@lodestar/utils";
|
|
11
12
|
import {ProcessShutdownCallback} from "@lodestar/validator";
|
|
@@ -45,13 +46,15 @@ export type BeaconNodeModules = {
|
|
|
45
46
|
export type BeaconNodeInitModules = {
|
|
46
47
|
opts: IBeaconNodeOptions;
|
|
47
48
|
config: BeaconConfig;
|
|
49
|
+
pubkey2index: PubkeyIndexMap;
|
|
50
|
+
index2pubkey: Index2PubkeyCache;
|
|
48
51
|
db: IBeaconDb;
|
|
49
52
|
logger: LoggerNode;
|
|
50
53
|
processShutdownCallback: ProcessShutdownCallback;
|
|
51
54
|
privateKey: PrivateKey;
|
|
52
55
|
dataDir: string;
|
|
53
56
|
peerStoreDir?: string;
|
|
54
|
-
anchorState:
|
|
57
|
+
anchorState: CachedBeaconStateAllForks;
|
|
55
58
|
isAnchorStateFinalized: boolean;
|
|
56
59
|
wsCheckpoint?: phase0.Checkpoint;
|
|
57
60
|
metricsRegistries?: Registry[];
|
|
@@ -146,6 +149,8 @@ export class BeaconNode {
|
|
|
146
149
|
static async init<T extends BeaconNode = BeaconNode>({
|
|
147
150
|
opts,
|
|
148
151
|
config,
|
|
152
|
+
pubkey2index,
|
|
153
|
+
index2pubkey,
|
|
149
154
|
db,
|
|
150
155
|
logger,
|
|
151
156
|
processShutdownCallback,
|
|
@@ -220,6 +225,8 @@ export class BeaconNode {
|
|
|
220
225
|
privateKey,
|
|
221
226
|
config,
|
|
222
227
|
clock,
|
|
228
|
+
pubkey2index,
|
|
229
|
+
index2pubkey,
|
|
223
230
|
dataDir,
|
|
224
231
|
db,
|
|
225
232
|
dbName: opts.db.name,
|
package/src/node/notifier.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
computeEpochAtSlot,
|
|
7
7
|
computeStartSlotAtEpoch,
|
|
8
8
|
isExecutionCachedStateType,
|
|
9
|
+
isMergeTransitionComplete,
|
|
9
10
|
} from "@lodestar/state-transition";
|
|
10
11
|
import {Epoch} from "@lodestar/types";
|
|
11
12
|
import {ErrorAborted, Logger, prettyBytes, prettyBytesShort, sleep} from "@lodestar/utils";
|
|
@@ -171,13 +172,18 @@ function getHeadExecutionInfo(
|
|
|
171
172
|
|
|
172
173
|
// Add execution status to notifier only if head is on/post bellatrix
|
|
173
174
|
if (isExecutionCachedStateType(headState)) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
175
|
+
if (isMergeTransitionComplete(headState)) {
|
|
176
|
+
const executionPayloadHashInfo =
|
|
177
|
+
headInfo.executionStatus !== ExecutionStatus.PreMerge ? headInfo.executionPayloadBlockHash : "empty";
|
|
178
|
+
const executionPayloadNumberInfo =
|
|
179
|
+
headInfo.executionStatus !== ExecutionStatus.PreMerge ? headInfo.executionPayloadNumber : NaN;
|
|
180
|
+
return [
|
|
181
|
+
`exec-block: ${executionStatusStr}(${executionPayloadNumberInfo} ${prettyBytesShort(
|
|
182
|
+
executionPayloadHashInfo
|
|
183
|
+
)})`,
|
|
184
|
+
];
|
|
185
|
+
}
|
|
186
|
+
return [`exec-block: ${executionStatusStr}`];
|
|
181
187
|
}
|
|
182
188
|
|
|
183
189
|
return [];
|
|
@@ -55,8 +55,7 @@ export async function verifyBlockProposerSignature(
|
|
|
55
55
|
if (blocks.length === 1 && blocks[0].message.slot === GENESIS_SLOT) return;
|
|
56
56
|
const signatures = blocks.reduce((sigs: ISignatureSet[], block) => {
|
|
57
57
|
// genesis block doesn't have valid signature
|
|
58
|
-
if (block.message.slot !== GENESIS_SLOT)
|
|
59
|
-
sigs.push(getBlockProposerSignatureSet(config, index2pubkey, state, block));
|
|
58
|
+
if (block.message.slot !== GENESIS_SLOT) sigs.push(getBlockProposerSignatureSet(config, index2pubkey, block));
|
|
60
59
|
return sigs;
|
|
61
60
|
}, []);
|
|
62
61
|
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { PubkeyIndexMap } from "@chainsafe/pubkey-index-map";
|
|
2
|
-
import { routes } from "@lodestar/api";
|
|
3
|
-
import { BeaconConfig } from "@lodestar/config";
|
|
4
|
-
import { CachedBeaconStateAllForks } from "@lodestar/state-transition";
|
|
5
|
-
import { ValidatorIndex } from "@lodestar/types";
|
|
6
|
-
export type AttestationsRewards = routes.beacon.AttestationsRewards;
|
|
7
|
-
export declare function computeAttestationsRewards(config: BeaconConfig, pubkey2index: PubkeyIndexMap, state: CachedBeaconStateAllForks, validatorIds?: (ValidatorIndex | string)[]): Promise<AttestationsRewards>;
|
|
8
|
-
//# sourceMappingURL=attestationsRewards.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attestationsRewards.d.ts","sourceRoot":"","sources":["../../../src/chain/rewards/attestationsRewards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAc9C,OAAO,EACL,yBAAyB,EAU1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAG/C,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC;AASpE,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,cAAc,EAC5B,KAAK,EAAE,yBAAyB,EAChC,YAAY,CAAC,EAAE,CAAC,cAAc,GAAG,MAAM,CAAC,EAAE,GACzC,OAAO,CAAC,mBAAmB,CAAC,CAyB9B"}
|