@lodestar/beacon-node 1.50.0-dev.072bf98853 → 1.50.0-dev.08c4bed201
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/api/impl/beacon/state/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/index.js +6 -4
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +2 -0
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/opPools/opPool.d.ts.map +1 -1
- package/lib/chain/opPools/opPool.js +1 -23
- package/lib/chain/opPools/opPool.js.map +1 -1
- package/lib/chain/opPools/proposerPreferencesPool.d.ts +4 -0
- package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -1
- package/lib/chain/opPools/proposerPreferencesPool.js +13 -1
- package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -1
- package/lib/chain/opPools/utils.d.ts +11 -0
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +22 -0
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/db/beacon.d.ts +2 -1
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +3 -1
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/buckets.d.ts +2 -1
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +1 -0
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/interface.d.ts +2 -1
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/index.d.ts +1 -0
- package/lib/db/repositories/index.d.ts.map +1 -1
- package/lib/db/repositories/index.js +1 -0
- package/lib/db/repositories/index.js.map +1 -1
- package/lib/db/repositories/proposerPreferences.d.ts +14 -0
- package/lib/db/repositories/proposerPreferences.d.ts.map +1 -0
- package/lib/db/repositories/proposerPreferences.js +21 -0
- package/lib/db/repositories/proposerPreferences.js.map +1 -0
- package/lib/network/core/events.d.ts +5 -1
- package/lib/network/core/events.d.ts.map +1 -1
- package/lib/network/core/events.js +8 -0
- package/lib/network/core/events.js.map +1 -1
- package/lib/util/asyncIterableToEvents.d.ts +10 -2
- package/lib/util/asyncIterableToEvents.d.ts.map +1 -1
- package/lib/util/asyncIterableToEvents.js +29 -3
- package/lib/util/asyncIterableToEvents.js.map +1 -1
- package/lib/util/metadata.d.ts.map +1 -1
- package/lib/util/metadata.js +2 -1
- package/lib/util/metadata.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/state/index.ts +13 -4
- package/src/chain/chain.ts +2 -0
- package/src/chain/opPools/opPool.ts +1 -31
- package/src/chain/opPools/proposerPreferencesPool.ts +20 -1
- package/src/chain/opPools/utils.ts +31 -0
- package/src/db/beacon.ts +3 -0
- package/src/db/buckets.ts +1 -0
- package/src/db/interface.ts +2 -0
- package/src/db/repositories/index.ts +1 -0
- package/src/db/repositories/proposerPreferences.ts +23 -0
- package/src/network/core/events.ts +16 -1
- package/src/util/asyncIterableToEvents.ts +44 -5
- package/src/util/metadata.ts +2 -1
|
@@ -55,7 +55,10 @@ export class AsyncIterableBridgeCaller {
|
|
|
55
55
|
},
|
|
56
56
|
async return() {
|
|
57
57
|
// This will be reached if the consumer called 'break' or 'return' early in the loop.
|
|
58
|
-
|
|
58
|
+
// Without the cancel the handler keeps producing items that cross the thread boundary just to be dropped
|
|
59
|
+
if (self.pending.delete(id)) {
|
|
60
|
+
self.events.emitRequestCancel({ id });
|
|
61
|
+
}
|
|
59
62
|
return { value: undefined, done: true };
|
|
60
63
|
},
|
|
61
64
|
};
|
|
@@ -92,18 +95,29 @@ export class AsyncIterableBridgeCaller {
|
|
|
92
95
|
export class AsyncIterableBridgeHandler {
|
|
93
96
|
events;
|
|
94
97
|
handler;
|
|
98
|
+
iterators = new Map();
|
|
95
99
|
constructor(events, handler) {
|
|
96
100
|
this.events = events;
|
|
97
101
|
this.handler = handler;
|
|
98
102
|
events.onRequest(this.onRequest.bind(this));
|
|
103
|
+
events.onRequestCancel(this.onRequestCancel.bind(this));
|
|
104
|
+
}
|
|
105
|
+
get iteratingCount() {
|
|
106
|
+
return this.iterators.size;
|
|
99
107
|
}
|
|
100
108
|
async onRequest(data) {
|
|
101
109
|
try {
|
|
102
|
-
|
|
110
|
+
const iterator = this.handler(data.callArgs)[Symbol.asyncIterator]();
|
|
111
|
+
this.iterators.set(data.id, iterator);
|
|
112
|
+
while (true) {
|
|
113
|
+
const result = await iterator.next();
|
|
114
|
+
if (result.done) {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
103
117
|
this.events.emitResponse({
|
|
104
118
|
type: IteratorEventType.next,
|
|
105
119
|
id: data.id,
|
|
106
|
-
item,
|
|
120
|
+
item: result.value,
|
|
107
121
|
});
|
|
108
122
|
}
|
|
109
123
|
this.events.emitResponse({
|
|
@@ -118,6 +132,18 @@ export class AsyncIterableBridgeHandler {
|
|
|
118
132
|
error: toThreadBoundaryError(e),
|
|
119
133
|
});
|
|
120
134
|
}
|
|
135
|
+
finally {
|
|
136
|
+
this.iterators.delete(data.id);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
onRequestCancel(data) {
|
|
140
|
+
const iterator = this.iterators.get(data.id);
|
|
141
|
+
if (!iterator?.return) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// An async generator queues return() behind the next() that is in flight, so at most one more
|
|
145
|
+
// item is produced before its finally blocks run. Any error surfaces through that next() call.
|
|
146
|
+
void iterator.return().catch(() => { });
|
|
121
147
|
}
|
|
122
148
|
}
|
|
123
149
|
//# sourceMappingURL=asyncIterableToEvents.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asyncIterableToEvents.js","sourceRoot":"","sources":["../../src/util/asyncIterableToEvents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAC;AACtC,OAAO,EAAsB,uBAAuB,EAAE,qBAAqB,EAAC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"asyncIterableToEvents.js","sourceRoot":"","sources":["../../src/util/asyncIterableToEvents.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/util/metadata.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEhE,wBAAgB,wBAAwB,CAAC,IAAI,CAAC,EAAE;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAC,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/util/metadata.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEhE,wBAAgB,wBAAwB,CAAC,IAAI,CAAC,EAAE;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAC,GAAG,aAAa,CAQlG;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAEpD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAE3D"}
|
package/lib/util/metadata.js
CHANGED
|
@@ -5,7 +5,8 @@ export function getLodestarClientVersion(info) {
|
|
|
5
5
|
code: ClientCode.LS,
|
|
6
6
|
name: "Lodestar",
|
|
7
7
|
version: info?.version ?? "",
|
|
8
|
-
commit
|
|
8
|
+
// engine_getClientVersionV1 defines commit as 4 bytes, so builds without git data must not send an empty one
|
|
9
|
+
commit: info?.commit ? info.commit.slice(0, 8) : "00000000",
|
|
9
10
|
};
|
|
10
11
|
}
|
|
11
12
|
/**
|
package/lib/util/metadata.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/util/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,UAAU,EAAC,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAC,UAAU,EAAgB,MAAM,uBAAuB,CAAC;AAEhE,MAAM,UAAU,wBAAwB,CAAC,IAA0C;IACjF,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,EAAE;QACnB,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,EAAE;QAC5B,MAAM,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/util/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,UAAU,EAAC,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAC,UAAU,EAAgB,MAAM,uBAAuB,CAAC;AAEhE,MAAM,UAAU,wBAAwB,CAAC,IAA0C;IACjF,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,EAAE;QACnB,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,EAAE;QAC5B,6GAA6G;QAC7G,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;KAC5D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAoB;IACjD,OAAO,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC"}
|
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.08c4bed201",
|
|
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.08c4bed201",
|
|
131
|
+
"@lodestar/config": "^1.50.0-dev.08c4bed201",
|
|
132
|
+
"@lodestar/db": "^1.50.0-dev.08c4bed201",
|
|
133
|
+
"@lodestar/fork-choice": "^1.50.0-dev.08c4bed201",
|
|
134
|
+
"@lodestar/logger": "^1.50.0-dev.08c4bed201",
|
|
135
|
+
"@lodestar/params": "^1.50.0-dev.08c4bed201",
|
|
136
|
+
"@lodestar/reqresp": "^1.50.0-dev.08c4bed201",
|
|
137
|
+
"@lodestar/state-transition": "^1.50.0-dev.08c4bed201",
|
|
138
|
+
"@lodestar/types": "^1.50.0-dev.08c4bed201",
|
|
139
|
+
"@lodestar/utils": "^1.50.0-dev.08c4bed201",
|
|
140
|
+
"@lodestar/validator": "^1.50.0-dev.08c4bed201",
|
|
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.08c4bed201",
|
|
162
|
+
"@lodestar/test-utils": "^1.50.0-dev.08c4bed201",
|
|
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": "70891683ed33187aca902723b5515d6a164ada13"
|
|
178
178
|
}
|
|
@@ -16,7 +16,14 @@ import {
|
|
|
16
16
|
isStatePostFulu,
|
|
17
17
|
isStatePostGloas,
|
|
18
18
|
} from "@lodestar/state-transition";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
ValidatorIndex,
|
|
21
|
+
getBuilderStatus,
|
|
22
|
+
getValidatorStatus,
|
|
23
|
+
mapToGeneralStatus,
|
|
24
|
+
ssz,
|
|
25
|
+
sszTypesFor,
|
|
26
|
+
} from "@lodestar/types";
|
|
20
27
|
import {ApiError} from "../../errors.js";
|
|
21
28
|
import {ApiModules} from "../../types.js";
|
|
22
29
|
import {assertUniqueItems} from "../../utils.js";
|
|
@@ -413,7 +420,9 @@ export function getBeaconStateApi({
|
|
|
413
420
|
const pendingDeposits = state.pendingDeposits;
|
|
414
421
|
|
|
415
422
|
return {
|
|
416
|
-
data: context?.returnBytes
|
|
423
|
+
data: context?.returnBytes
|
|
424
|
+
? sszTypesFor(state.forkName).PendingDeposits.serialize(pendingDeposits)
|
|
425
|
+
: pendingDeposits,
|
|
417
426
|
meta: {executionOptimistic, finalized, version: fork},
|
|
418
427
|
};
|
|
419
428
|
},
|
|
@@ -430,7 +439,7 @@ export function getBeaconStateApi({
|
|
|
430
439
|
|
|
431
440
|
return {
|
|
432
441
|
data: context?.returnBytes
|
|
433
|
-
?
|
|
442
|
+
? sszTypesFor(state.forkName).PendingPartialWithdrawals.serialize(pendingPartialWithdrawals)
|
|
434
443
|
: pendingPartialWithdrawals,
|
|
435
444
|
meta: {executionOptimistic, finalized, version: fork},
|
|
436
445
|
};
|
|
@@ -448,7 +457,7 @@ export function getBeaconStateApi({
|
|
|
448
457
|
|
|
449
458
|
return {
|
|
450
459
|
data: context?.returnBytes
|
|
451
|
-
?
|
|
460
|
+
? sszTypesFor(state.forkName).PendingConsolidations.serialize(pendingConsolidations)
|
|
452
461
|
: pendingConsolidations,
|
|
453
462
|
meta: {executionOptimistic, finalized, version: fork},
|
|
454
463
|
};
|
package/src/chain/chain.ts
CHANGED
|
@@ -620,12 +620,14 @@ export class BeaconChain implements IBeaconChain {
|
|
|
620
620
|
async loadFromDisk(): Promise<void> {
|
|
621
621
|
await this.regen.init();
|
|
622
622
|
await this.opPool.fromPersisted(this.db, this.getHeadState(), this.bls, this.clock.currentSlot);
|
|
623
|
+
await this.proposerPreferencesPool.fromPersisted(this.db, this.clock.currentSlot);
|
|
623
624
|
}
|
|
624
625
|
|
|
625
626
|
/** Persist in-memory data to the DB. Call at least once before stopping the process */
|
|
626
627
|
async persistToDisk(): Promise<void> {
|
|
627
628
|
await this.archiveStore.persistToDisk();
|
|
628
629
|
await this.opPool.toPersisted(this.db);
|
|
630
|
+
await this.proposerPreferencesPool.toPersisted(this.db);
|
|
629
631
|
}
|
|
630
632
|
|
|
631
633
|
getHeadState(): IBeaconStateView {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
-
import {DbBatch, Id, Repository} from "@lodestar/db";
|
|
3
2
|
import {
|
|
4
3
|
BLS_WITHDRAWAL_PREFIX,
|
|
5
4
|
ForkName,
|
|
@@ -42,6 +41,7 @@ import {
|
|
|
42
41
|
getAttesterSlashingSignatureDomains,
|
|
43
42
|
getProposerSlashingSignatureDomain,
|
|
44
43
|
isValidBlsToExecutionChangeForBlockInclusion,
|
|
44
|
+
persistDiff,
|
|
45
45
|
} from "./utils.js";
|
|
46
46
|
|
|
47
47
|
type HexRoot = string;
|
|
@@ -500,33 +500,3 @@ function isVoluntaryExitSignatureIncludable(stateFork: ForkSeq, voluntaryExitFor
|
|
|
500
500
|
function isSlashableAtEpoch(validator: phase0.Validator, epoch: Epoch): boolean {
|
|
501
501
|
return !validator.slashed && validator.activationEpoch <= epoch && epoch < validator.withdrawableEpoch;
|
|
502
502
|
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Persist target items `items` in `dbRepo` doing minimum put and delete writes.
|
|
506
|
-
* Reads all keys in repository to compute the diff between current persisted data and target data.
|
|
507
|
-
*/
|
|
508
|
-
async function persistDiff<K extends Id, V>(
|
|
509
|
-
dbRepo: Repository<K, V>,
|
|
510
|
-
items: {key: K; value: V}[],
|
|
511
|
-
serializeKey: (key: K) => number | string,
|
|
512
|
-
opts: {updateExisting?: boolean} = {}
|
|
513
|
-
): Promise<void> {
|
|
514
|
-
const persistedKeys = await dbRepo.keys();
|
|
515
|
-
const batch: DbBatch<K, V> = [];
|
|
516
|
-
|
|
517
|
-
const persistedKeysSerialized = new Set(persistedKeys.map(serializeKey));
|
|
518
|
-
for (const item of items) {
|
|
519
|
-
if (opts.updateExisting || !persistedKeysSerialized.has(serializeKey(item.key))) {
|
|
520
|
-
batch.push({type: "put", key: item.key, value: item.value});
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
const targetKeysSerialized = new Set(items.map((item) => serializeKey(item.key)));
|
|
525
|
-
for (const persistedKey of persistedKeys) {
|
|
526
|
-
if (!targetKeysSerialized.has(serializeKey(persistedKey))) {
|
|
527
|
-
batch.push({type: "del", key: persistedKey});
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
if (batch.length > 0) await dbRepo.batch(batch);
|
|
532
|
-
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {RootHex, Slot, ValidatorIndex, gloas} from "@lodestar/types";
|
|
2
|
-
import {toRootHex} from "@lodestar/utils";
|
|
2
|
+
import {toHex, toRootHex} from "@lodestar/utils";
|
|
3
|
+
import {IBeaconDb} from "../../db/index.js";
|
|
4
|
+
import {persistDiff} from "./utils.js";
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Pool of validated `SignedProposerPreferences` indexed by `(slot, dependent_root)`.
|
|
@@ -64,4 +66,21 @@ export class ProposerPreferencesPool {
|
|
|
64
66
|
if (slot < currentSlot) this.bySlot.delete(slot);
|
|
65
67
|
}
|
|
66
68
|
}
|
|
69
|
+
|
|
70
|
+
/** Restore the preferences of upcoming slots, they were validated before they were persisted */
|
|
71
|
+
async fromPersisted(db: IBeaconDb, currentSlot: Slot): Promise<void> {
|
|
72
|
+
for (const signed of await db.proposerPreferences.values()) {
|
|
73
|
+
if (signed.message.proposalSlot >= currentSlot) {
|
|
74
|
+
this.add(signed);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async toPersisted(db: IBeaconDb): Promise<void> {
|
|
80
|
+
await persistDiff(
|
|
81
|
+
db.proposerPreferences,
|
|
82
|
+
this.getAll().map((signed) => ({key: db.proposerPreferences.getId(signed), value: signed})),
|
|
83
|
+
toHex
|
|
84
|
+
);
|
|
85
|
+
}
|
|
67
86
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {Signature} from "@chainsafe/lodestar-z/blst";
|
|
2
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
|
+
import {DbBatch, Id, Repository} from "@lodestar/db";
|
|
3
4
|
import {BLS_WITHDRAWAL_PREFIX, DOMAIN_BEACON_ATTESTER, DOMAIN_BEACON_PROPOSER} from "@lodestar/params";
|
|
4
5
|
import {IBeaconStateView, computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
5
6
|
import {AttesterSlashing, Domain, Slot, capella, phase0} from "@lodestar/types";
|
|
@@ -91,3 +92,33 @@ export function isValidBlsToExecutionChangeForBlockInclusion(
|
|
|
91
92
|
export function isElectraAggregate(aggregate: AggregateFast): aggregate is AggregateFastElectra {
|
|
92
93
|
return (aggregate as AggregateFastElectra).committeeBits !== undefined;
|
|
93
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Persist target items `items` in `dbRepo` doing minimum put and delete writes.
|
|
98
|
+
* Reads all keys in repository to compute the diff between current persisted data and target data.
|
|
99
|
+
*/
|
|
100
|
+
export async function persistDiff<K extends Id, V>(
|
|
101
|
+
dbRepo: Repository<K, V>,
|
|
102
|
+
items: {key: K; value: V}[],
|
|
103
|
+
serializeKey: (key: K) => number | string,
|
|
104
|
+
opts: {updateExisting?: boolean} = {}
|
|
105
|
+
): Promise<void> {
|
|
106
|
+
const persistedKeys = await dbRepo.keys();
|
|
107
|
+
const batch: DbBatch<K, V> = [];
|
|
108
|
+
|
|
109
|
+
const persistedKeysSerialized = new Set(persistedKeys.map(serializeKey));
|
|
110
|
+
for (const item of items) {
|
|
111
|
+
if (opts.updateExisting || !persistedKeysSerialized.has(serializeKey(item.key))) {
|
|
112
|
+
batch.push({type: "put", key: item.key, value: item.value});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const targetKeysSerialized = new Set(items.map((item) => serializeKey(item.key)));
|
|
117
|
+
for (const persistedKey of persistedKeys) {
|
|
118
|
+
if (!targetKeysSerialized.has(serializeKey(persistedKey))) {
|
|
119
|
+
batch.push({type: "del", key: persistedKey});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (batch.length > 0) await dbRepo.batch(batch);
|
|
124
|
+
}
|
package/src/db/beacon.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
DataColumnSidecarRepository,
|
|
23
23
|
ExecutionPayloadEnvelopeArchiveRepository,
|
|
24
24
|
ExecutionPayloadEnvelopeRepository,
|
|
25
|
+
ProposerPreferencesRepository,
|
|
25
26
|
ProposerSlashingRepository,
|
|
26
27
|
StateArchiveRepository,
|
|
27
28
|
SyncCommitteeRepository,
|
|
@@ -53,6 +54,7 @@ export class BeaconDb implements IBeaconDb {
|
|
|
53
54
|
|
|
54
55
|
voluntaryExit: VoluntaryExitRepository;
|
|
55
56
|
proposerSlashing: ProposerSlashingRepository;
|
|
57
|
+
proposerPreferences: ProposerPreferencesRepository;
|
|
56
58
|
attesterSlashing: AttesterSlashingRepository;
|
|
57
59
|
blsToExecutionChange: BLSToExecutionChangeRepository;
|
|
58
60
|
|
|
@@ -89,6 +91,7 @@ export class BeaconDb implements IBeaconDb {
|
|
|
89
91
|
this.voluntaryExit = new VoluntaryExitRepository(config, db);
|
|
90
92
|
this.blsToExecutionChange = new BLSToExecutionChangeRepository(config, db);
|
|
91
93
|
this.proposerSlashing = new ProposerSlashingRepository(config, db);
|
|
94
|
+
this.proposerPreferences = new ProposerPreferencesRepository(config, db);
|
|
92
95
|
this.attesterSlashing = new AttesterSlashingRepository(config, db);
|
|
93
96
|
|
|
94
97
|
// lightclient
|
package/src/db/buckets.ts
CHANGED
|
@@ -73,6 +73,7 @@ export enum Bucket {
|
|
|
73
73
|
gloas_executionPayloadEnvelope = 59, // GLOAS BeaconBlockRoot -> SignedExecutionPayloadEnvelope
|
|
74
74
|
gloas_executionPayloadEnvelopeArchive = 60, // GLOAS Slot -> SignedExecutionPayloadEnvelope, or 0x00 + SignedExecutionPayloadHeaderEnvelope
|
|
75
75
|
earliestAvailableSlot = 61, // singleton -> Slot
|
|
76
|
+
gloas_proposerPreferences = 62, // Slot || DependentRoot -> SignedProposerPreferences
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export function getBucketNameByValue<T extends Bucket>(enumValue: T): keyof typeof Bucket {
|
package/src/db/interface.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
DataColumnSidecarRepository,
|
|
18
18
|
ExecutionPayloadEnvelopeArchiveRepository,
|
|
19
19
|
ExecutionPayloadEnvelopeRepository,
|
|
20
|
+
ProposerPreferencesRepository,
|
|
20
21
|
ProposerSlashingRepository,
|
|
21
22
|
StateArchiveRepository,
|
|
22
23
|
SyncCommitteeRepository,
|
|
@@ -52,6 +53,7 @@ export interface IBeaconDb {
|
|
|
52
53
|
// op pool
|
|
53
54
|
voluntaryExit: VoluntaryExitRepository;
|
|
54
55
|
proposerSlashing: ProposerSlashingRepository;
|
|
56
|
+
proposerPreferences: ProposerPreferencesRepository;
|
|
55
57
|
attesterSlashing: AttesterSlashingRepository;
|
|
56
58
|
blsToExecutionChange: BLSToExecutionChangeRepository;
|
|
57
59
|
|
|
@@ -18,6 +18,7 @@ export {BestLightClientUpdateRepository} from "./lightclientBestUpdate.js";
|
|
|
18
18
|
export {CheckpointHeaderRepository} from "./lightclientCheckpointHeader.js";
|
|
19
19
|
export {SyncCommitteeRepository} from "./lightclientSyncCommittee.js";
|
|
20
20
|
export {SyncCommitteeWitnessRepository} from "./lightclientSyncCommitteeWitness.js";
|
|
21
|
+
export {ProposerPreferencesRepository} from "./proposerPreferences.js";
|
|
21
22
|
export {ProposerSlashingRepository} from "./proposerSlashing.js";
|
|
22
23
|
export {StateArchiveRepository} from "./stateArchive.js";
|
|
23
24
|
export {VoluntaryExitRepository} from "./voluntaryExit.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
+
import {Db, Repository} from "@lodestar/db";
|
|
3
|
+
import {gloas, ssz} from "@lodestar/types";
|
|
4
|
+
import {intToBytes} from "@lodestar/utils";
|
|
5
|
+
import {Bucket, getBucketNameByValue} from "../buckets.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* SignedProposerPreferences indexed by proposal slot and dependent root
|
|
9
|
+
*
|
|
10
|
+
* Added via gossip or api
|
|
11
|
+
* Removed once the proposal slot has passed
|
|
12
|
+
*/
|
|
13
|
+
export class ProposerPreferencesRepository extends Repository<Uint8Array, gloas.SignedProposerPreferences> {
|
|
14
|
+
constructor(config: ChainForkConfig, db: Db) {
|
|
15
|
+
const bucket = Bucket.gloas_proposerPreferences;
|
|
16
|
+
super(config, db, bucket, ssz.gloas.SignedProposerPreferences, getBucketNameByValue(bucket));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getId(value: gloas.SignedProposerPreferences): Uint8Array {
|
|
20
|
+
const {proposalSlot, dependentRoot} = value.message;
|
|
21
|
+
return Buffer.concat([intToBytes(proposalSlot, 8, "be"), dependentRoot]);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
import EventEmitter from "node:events";
|
|
2
2
|
import {ResponseIncoming, ResponseOutgoing} from "@lodestar/reqresp";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
AsyncIterableEventBus,
|
|
5
|
+
IteratorEvent,
|
|
6
|
+
RequestCancelEvent,
|
|
7
|
+
RequestEvent,
|
|
8
|
+
} from "../../util/asyncIterableToEvents.js";
|
|
4
9
|
import {StrictEventEmitterSingleArg} from "../../util/strictEvents.js";
|
|
5
10
|
import {EventDirection} from "../events.js";
|
|
6
11
|
import {IncomingRequestArgs, OutgoingRequestArgs} from "../reqresp/types.js";
|
|
7
12
|
|
|
8
13
|
export enum ReqRespBridgeEvent {
|
|
9
14
|
outgoingRequest = "reqresp.outgoingRequest",
|
|
15
|
+
outgoingRequestCancel = "reqresp.outgoingRequestCancel",
|
|
10
16
|
outgoingResponse = "reqresp.outgoingResponse",
|
|
11
17
|
incomingRequest = "reqresp.incomingRequest",
|
|
18
|
+
incomingRequestCancel = "reqresp.incomingRequestCancel",
|
|
12
19
|
incomingResponse = "reqresp.incomingResponse",
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
export type ReqRespBridgeEventData = {
|
|
16
23
|
[ReqRespBridgeEvent.outgoingRequest]: RequestEvent<OutgoingRequestArgs>;
|
|
24
|
+
[ReqRespBridgeEvent.outgoingRequestCancel]: RequestCancelEvent;
|
|
17
25
|
[ReqRespBridgeEvent.outgoingResponse]: IteratorEvent<ResponseOutgoing>;
|
|
18
26
|
[ReqRespBridgeEvent.incomingRequest]: RequestEvent<IncomingRequestArgs>;
|
|
27
|
+
[ReqRespBridgeEvent.incomingRequestCancel]: RequestCancelEvent;
|
|
19
28
|
[ReqRespBridgeEvent.incomingResponse]: IteratorEvent<ResponseIncoming>;
|
|
20
29
|
};
|
|
21
30
|
|
|
@@ -26,8 +35,10 @@ export class ReqRespBridgeEventBus extends (EventEmitter as {new (): IReqRespBri
|
|
|
26
35
|
// NOTE: If the same event is on this two arrays it can create an infinite cycle
|
|
27
36
|
export const reqRespBridgeEventDirection: Record<ReqRespBridgeEvent, EventDirection> = {
|
|
28
37
|
[ReqRespBridgeEvent.outgoingRequest]: EventDirection.mainToWorker,
|
|
38
|
+
[ReqRespBridgeEvent.outgoingRequestCancel]: EventDirection.mainToWorker,
|
|
29
39
|
[ReqRespBridgeEvent.outgoingResponse]: EventDirection.mainToWorker,
|
|
30
40
|
[ReqRespBridgeEvent.incomingRequest]: EventDirection.workerToMain,
|
|
41
|
+
[ReqRespBridgeEvent.incomingRequestCancel]: EventDirection.workerToMain,
|
|
31
42
|
[ReqRespBridgeEvent.incomingResponse]: EventDirection.workerToMain,
|
|
32
43
|
};
|
|
33
44
|
|
|
@@ -36,8 +47,10 @@ export function getReqRespBridgeReqEvents(
|
|
|
36
47
|
): AsyncIterableEventBus<OutgoingRequestArgs, ResponseIncoming> {
|
|
37
48
|
return {
|
|
38
49
|
emitRequest: (data) => events.emit(ReqRespBridgeEvent.outgoingRequest, data),
|
|
50
|
+
emitRequestCancel: (data) => events.emit(ReqRespBridgeEvent.outgoingRequestCancel, data),
|
|
39
51
|
emitResponse: (data) => events.emit(ReqRespBridgeEvent.incomingResponse, data),
|
|
40
52
|
onRequest: (cb) => events.on(ReqRespBridgeEvent.outgoingRequest, cb),
|
|
53
|
+
onRequestCancel: (cb) => events.on(ReqRespBridgeEvent.outgoingRequestCancel, cb),
|
|
41
54
|
onResponse: (cb) => events.on(ReqRespBridgeEvent.incomingResponse, cb),
|
|
42
55
|
};
|
|
43
56
|
}
|
|
@@ -47,8 +60,10 @@ export function getReqRespBridgeRespEvents(
|
|
|
47
60
|
): AsyncIterableEventBus<IncomingRequestArgs, ResponseOutgoing> {
|
|
48
61
|
return {
|
|
49
62
|
emitRequest: (data) => events.emit(ReqRespBridgeEvent.incomingRequest, data),
|
|
63
|
+
emitRequestCancel: (data) => events.emit(ReqRespBridgeEvent.incomingRequestCancel, data),
|
|
50
64
|
emitResponse: (data) => events.emit(ReqRespBridgeEvent.outgoingResponse, data),
|
|
51
65
|
onRequest: (cb) => events.on(ReqRespBridgeEvent.incomingRequest, cb),
|
|
66
|
+
onRequestCancel: (cb) => events.on(ReqRespBridgeEvent.incomingRequestCancel, cb),
|
|
52
67
|
onResponse: (cb) => events.on(ReqRespBridgeEvent.outgoingResponse, cb),
|
|
53
68
|
};
|
|
54
69
|
}
|
|
@@ -6,6 +6,10 @@ export type RequestEvent<T> = {
|
|
|
6
6
|
id: number;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
export type RequestCancelEvent = {
|
|
10
|
+
id: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
9
13
|
export enum IteratorEventType {
|
|
10
14
|
next = "iterator.next",
|
|
11
15
|
done = "iterator.done",
|
|
@@ -19,8 +23,10 @@ export type IteratorEvent<V> =
|
|
|
19
23
|
|
|
20
24
|
export type AsyncIterableEventBus<Args, Item> = {
|
|
21
25
|
emitRequest(data: RequestEvent<Args>): void;
|
|
26
|
+
emitRequestCancel(data: RequestCancelEvent): void;
|
|
22
27
|
emitResponse(data: IteratorEvent<Item>): void;
|
|
23
28
|
onRequest(handler: (data: RequestEvent<Args>) => void): void;
|
|
29
|
+
onRequestCancel(handler: (data: RequestCancelEvent) => void): void;
|
|
24
30
|
onResponse(handler: (data: IteratorEvent<Item>) => void): void;
|
|
25
31
|
};
|
|
26
32
|
|
|
@@ -37,7 +43,9 @@ export class AsyncIterableBridgeCaller<Args, Item> {
|
|
|
37
43
|
// TODO: Consider expiring the requests after no reply for long enough, t
|
|
38
44
|
private readonly pending = new Map<number, PendingItem<Item>>();
|
|
39
45
|
|
|
40
|
-
constructor(
|
|
46
|
+
constructor(
|
|
47
|
+
private readonly events: Pick<AsyncIterableEventBus<Args, Item>, "onResponse" | "emitRequest" | "emitRequestCancel">
|
|
48
|
+
) {
|
|
41
49
|
events.onResponse(this.onResponse.bind(this));
|
|
42
50
|
}
|
|
43
51
|
|
|
@@ -89,7 +97,10 @@ export class AsyncIterableBridgeCaller<Args, Item> {
|
|
|
89
97
|
|
|
90
98
|
async return() {
|
|
91
99
|
// This will be reached if the consumer called 'break' or 'return' early in the loop.
|
|
92
|
-
|
|
100
|
+
// Without the cancel the handler keeps producing items that cross the thread boundary just to be dropped
|
|
101
|
+
if (self.pending.delete(id)) {
|
|
102
|
+
self.events.emitRequestCancel({id});
|
|
103
|
+
}
|
|
93
104
|
return {value: undefined, done: true};
|
|
94
105
|
},
|
|
95
106
|
};
|
|
@@ -132,20 +143,35 @@ export class AsyncIterableBridgeCaller<Args, Item> {
|
|
|
132
143
|
}
|
|
133
144
|
|
|
134
145
|
export class AsyncIterableBridgeHandler<Args, Item> {
|
|
146
|
+
private readonly iterators = new Map<number, AsyncIterator<Item>>();
|
|
147
|
+
|
|
135
148
|
constructor(
|
|
136
|
-
private readonly events: Pick<AsyncIterableEventBus<Args, Item>, "onRequest" | "emitResponse">,
|
|
149
|
+
private readonly events: Pick<AsyncIterableEventBus<Args, Item>, "onRequest" | "onRequestCancel" | "emitResponse">,
|
|
137
150
|
private readonly handler: (args: Args) => AsyncIterable<Item>
|
|
138
151
|
) {
|
|
139
152
|
events.onRequest(this.onRequest.bind(this));
|
|
153
|
+
events.onRequestCancel(this.onRequestCancel.bind(this));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
get iteratingCount(): number {
|
|
157
|
+
return this.iterators.size;
|
|
140
158
|
}
|
|
141
159
|
|
|
142
160
|
private async onRequest(data: RequestEvent<Args>): Promise<void> {
|
|
143
161
|
try {
|
|
144
|
-
|
|
162
|
+
const iterator = this.handler(data.callArgs)[Symbol.asyncIterator]();
|
|
163
|
+
this.iterators.set(data.id, iterator);
|
|
164
|
+
|
|
165
|
+
while (true) {
|
|
166
|
+
const result = await iterator.next();
|
|
167
|
+
if (result.done) {
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
|
|
145
171
|
this.events.emitResponse({
|
|
146
172
|
type: IteratorEventType.next,
|
|
147
173
|
id: data.id,
|
|
148
|
-
item,
|
|
174
|
+
item: result.value,
|
|
149
175
|
});
|
|
150
176
|
}
|
|
151
177
|
|
|
@@ -159,6 +185,19 @@ export class AsyncIterableBridgeHandler<Args, Item> {
|
|
|
159
185
|
id: data.id,
|
|
160
186
|
error: toThreadBoundaryError(e as Error),
|
|
161
187
|
});
|
|
188
|
+
} finally {
|
|
189
|
+
this.iterators.delete(data.id);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private onRequestCancel(data: RequestCancelEvent): void {
|
|
194
|
+
const iterator = this.iterators.get(data.id);
|
|
195
|
+
if (!iterator?.return) {
|
|
196
|
+
return;
|
|
162
197
|
}
|
|
198
|
+
|
|
199
|
+
// An async generator queues return() behind the next() that is in flight, so at most one more
|
|
200
|
+
// item is produced before its finally blocks run. Any error surfaces through that next() call.
|
|
201
|
+
void iterator.return().catch(() => {});
|
|
163
202
|
}
|
|
164
203
|
}
|
package/src/util/metadata.ts
CHANGED
|
@@ -6,7 +6,8 @@ export function getLodestarClientVersion(info?: {version?: string; commit?: stri
|
|
|
6
6
|
code: ClientCode.LS,
|
|
7
7
|
name: "Lodestar",
|
|
8
8
|
version: info?.version ?? "",
|
|
9
|
-
commit
|
|
9
|
+
// engine_getClientVersionV1 defines commit as 4 bytes, so builds without git data must not send an empty one
|
|
10
|
+
commit: info?.commit ? info.commit.slice(0, 8) : "00000000",
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
13
|
|