@lodestar/api 1.45.0-dev.51a1c44b27 → 1.45.0-dev.6568180f96
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/beacon/routes/beacon/block.d.ts +10 -1
- package/lib/beacon/routes/beacon/block.d.ts.map +1 -1
- package/lib/beacon/routes/beacon/block.js +34 -12
- package/lib/beacon/routes/beacon/block.js.map +1 -1
- package/lib/beacon/routes/beacon/index.d.ts +1 -1
- package/lib/beacon/routes/beacon/index.d.ts.map +1 -1
- package/lib/beacon/routes/beacon/index.js.map +1 -1
- package/lib/beacon/routes/beacon/pool.d.ts +1 -35
- package/lib/beacon/routes/beacon/pool.d.ts.map +1 -1
- package/lib/beacon/routes/beacon/pool.js +1 -44
- package/lib/beacon/routes/beacon/pool.js.map +1 -1
- package/lib/beacon/routes/beacon/state.d.ts +54 -2
- package/lib/beacon/routes/beacon/state.d.ts.map +1 -1
- package/lib/beacon/routes/beacon/state.js +34 -1
- package/lib/beacon/routes/beacon/state.js.map +1 -1
- package/lib/beacon/routes/events.d.ts +118 -3
- package/lib/beacon/routes/events.d.ts.map +1 -1
- package/lib/beacon/routes/events.js +4 -0
- package/lib/beacon/routes/events.js.map +1 -1
- package/lib/beacon/routes/node.d.ts +2 -0
- package/lib/beacon/routes/node.d.ts.map +1 -1
- package/lib/beacon/routes/node.js +2 -0
- package/lib/beacon/routes/node.js.map +1 -1
- package/lib/beacon/routes/validator.d.ts +45 -5
- package/lib/beacon/routes/validator.d.ts.map +1 -1
- package/lib/beacon/routes/validator.js +50 -9
- package/lib/beacon/routes/validator.js.map +1 -1
- package/lib/utils/metadata.d.ts +2 -0
- package/lib/utils/metadata.d.ts.map +1 -1
- package/lib/utils/metadata.js +2 -0
- package/lib/utils/metadata.js.map +1 -1
- package/lib/utils/schema.d.ts +2 -1
- package/lib/utils/schema.d.ts.map +1 -1
- package/lib/utils/schema.js +3 -0
- package/lib/utils/schema.js.map +1 -1
- package/lib/utils/serdes.d.ts +2 -0
- package/lib/utils/serdes.d.ts.map +1 -1
- package/lib/utils/serdes.js +2 -0
- package/lib/utils/serdes.js.map +1 -1
- package/lib/utils/server/handler.d.ts.map +1 -1
- package/lib/utils/server/handler.js +4 -0
- package/lib/utils/server/handler.js.map +1 -1
- package/package.json +10 -10
- package/src/beacon/routes/beacon/block.ts +51 -14
- package/src/beacon/routes/beacon/index.ts +3 -0
- package/src/beacon/routes/beacon/pool.ts +0 -72
- package/src/beacon/routes/beacon/state.ts +63 -2
- package/src/beacon/routes/events.ts +5 -0
- package/src/beacon/routes/node.ts +3 -1
- package/src/beacon/routes/validator.ts +95 -11
- package/src/utils/metadata.ts +2 -0
- package/src/utils/schema.ts +3 -0
- package/src/utils/serdes.ts +3 -0
- package/src/utils/server/handler.ts +5 -0
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
Slot,
|
|
19
19
|
deneb,
|
|
20
20
|
gloas,
|
|
21
|
+
isSignedExecutionPayloadEnvelopeContents,
|
|
21
22
|
ssz,
|
|
22
23
|
sszTypesFor,
|
|
23
24
|
} from "@lodestar/types";
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
ExecutionOptimisticFinalizedAndVersionMeta,
|
|
33
34
|
MetaHeader,
|
|
34
35
|
} from "../../../utils/metadata.js";
|
|
36
|
+
import {toBoolean} from "../../../utils/serdes.js";
|
|
35
37
|
import {WireFormat} from "../../../utils/wireFormat.js";
|
|
36
38
|
|
|
37
39
|
export const BlockHeaderResponseType = new ContainerType({
|
|
@@ -187,11 +189,22 @@ export type Endpoints = {
|
|
|
187
189
|
* Instructs the beacon node to broadcast a signed execution payload envelope to the network,
|
|
188
190
|
* to be gossiped for payload validation. A success response (20x) indicates that the envelope
|
|
189
191
|
* passed gossip validation and was successfully broadcast onto the network.
|
|
192
|
+
*
|
|
193
|
+
* The request body is either a `SignedExecutionPayloadEnvelopeContents` (envelope with blobs
|
|
194
|
+
* and KZG proofs, stateless flow) or a `SignedExecutionPayloadEnvelope` (stateful flow,
|
|
195
|
+
* the beacon node attaches blobs and KZG proofs from its block production cache).
|
|
190
196
|
*/
|
|
191
197
|
publishExecutionPayloadEnvelope: Endpoint<
|
|
192
198
|
"POST",
|
|
193
|
-
{
|
|
194
|
-
|
|
199
|
+
{
|
|
200
|
+
signedEnvelopeOrContents: gloas.SignedExecutionPayloadEnvelopeContents | gloas.SignedExecutionPayloadEnvelope;
|
|
201
|
+
broadcastValidation?: BroadcastValidation;
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
body: unknown;
|
|
205
|
+
headers: {[MetaHeader.Version]: string; [MetaHeader.BlobDataIncluded]: string};
|
|
206
|
+
query: {broadcast_validation?: string};
|
|
207
|
+
},
|
|
195
208
|
EmptyResponseData,
|
|
196
209
|
EmptyMeta
|
|
197
210
|
>;
|
|
@@ -453,40 +466,64 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
453
466
|
url: "/eth/v1/beacon/execution_payload_envelopes",
|
|
454
467
|
method: "POST",
|
|
455
468
|
req: {
|
|
456
|
-
writeReqJson: ({
|
|
457
|
-
const
|
|
469
|
+
writeReqJson: ({signedEnvelopeOrContents, broadcastValidation}) => {
|
|
470
|
+
const blobDataIncluded = isSignedExecutionPayloadEnvelopeContents(signedEnvelopeOrContents);
|
|
471
|
+
const fork = config.getForkName(
|
|
472
|
+
(blobDataIncluded ? signedEnvelopeOrContents.signedExecutionPayloadEnvelope : signedEnvelopeOrContents)
|
|
473
|
+
.message.payload.slotNumber
|
|
474
|
+
);
|
|
458
475
|
return {
|
|
459
|
-
body:
|
|
476
|
+
body: blobDataIncluded
|
|
477
|
+
? getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelopeContents.toJson(signedEnvelopeOrContents)
|
|
478
|
+
: getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelope.toJson(signedEnvelopeOrContents),
|
|
460
479
|
headers: {
|
|
461
480
|
[MetaHeader.Version]: fork,
|
|
481
|
+
[MetaHeader.BlobDataIncluded]: blobDataIncluded.toString(),
|
|
462
482
|
},
|
|
483
|
+
query: {broadcast_validation: broadcastValidation},
|
|
463
484
|
};
|
|
464
485
|
},
|
|
465
|
-
parseReqJson: ({body, headers}) => {
|
|
486
|
+
parseReqJson: ({body, headers, query}) => {
|
|
466
487
|
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
488
|
+
const blobDataIncluded = toBoolean(fromHeaders(headers, MetaHeader.BlobDataIncluded));
|
|
467
489
|
return {
|
|
468
|
-
|
|
490
|
+
signedEnvelopeOrContents: blobDataIncluded
|
|
491
|
+
? getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelopeContents.fromJson(body)
|
|
492
|
+
: getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelope.fromJson(body),
|
|
493
|
+
broadcastValidation: query.broadcast_validation as BroadcastValidation,
|
|
469
494
|
};
|
|
470
495
|
},
|
|
471
|
-
writeReqSsz: ({
|
|
472
|
-
const
|
|
496
|
+
writeReqSsz: ({signedEnvelopeOrContents, broadcastValidation}) => {
|
|
497
|
+
const blobDataIncluded = isSignedExecutionPayloadEnvelopeContents(signedEnvelopeOrContents);
|
|
498
|
+
const fork = config.getForkName(
|
|
499
|
+
(blobDataIncluded ? signedEnvelopeOrContents.signedExecutionPayloadEnvelope : signedEnvelopeOrContents)
|
|
500
|
+
.message.payload.slotNumber
|
|
501
|
+
);
|
|
473
502
|
return {
|
|
474
|
-
body:
|
|
503
|
+
body: blobDataIncluded
|
|
504
|
+
? getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelopeContents.serialize(signedEnvelopeOrContents)
|
|
505
|
+
: getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelope.serialize(signedEnvelopeOrContents),
|
|
475
506
|
headers: {
|
|
476
507
|
[MetaHeader.Version]: fork,
|
|
508
|
+
[MetaHeader.BlobDataIncluded]: blobDataIncluded.toString(),
|
|
477
509
|
},
|
|
510
|
+
query: {broadcast_validation: broadcastValidation},
|
|
478
511
|
};
|
|
479
512
|
},
|
|
480
|
-
parseReqSsz: ({body, headers}) => {
|
|
513
|
+
parseReqSsz: ({body, headers, query}) => {
|
|
481
514
|
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
515
|
+
const blobDataIncluded = toBoolean(fromHeaders(headers, MetaHeader.BlobDataIncluded));
|
|
482
516
|
return {
|
|
483
|
-
|
|
484
|
-
getPostGloasForkTypes(fork).
|
|
517
|
+
signedEnvelopeOrContents: blobDataIncluded
|
|
518
|
+
? getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelopeContents.deserialize(body)
|
|
519
|
+
: getPostGloasForkTypes(fork).SignedExecutionPayloadEnvelope.deserialize(body),
|
|
520
|
+
broadcastValidation: query.broadcast_validation as BroadcastValidation,
|
|
485
521
|
};
|
|
486
522
|
},
|
|
487
523
|
schema: {
|
|
488
524
|
body: Schema.Object,
|
|
489
|
-
|
|
525
|
+
query: {broadcast_validation: Schema.String},
|
|
526
|
+
headers: {[MetaHeader.Version]: Schema.String, [MetaHeader.BlobDataIncluded]: Schema.String},
|
|
490
527
|
},
|
|
491
528
|
},
|
|
492
529
|
resp: EmptyResponseCodec,
|
|
@@ -15,6 +15,9 @@ export type {BlockHeaderResponse, BlockId} from "./block.js";
|
|
|
15
15
|
export {BroadcastValidation} from "./block.js";
|
|
16
16
|
// TODO: Review if re-exporting all these types is necessary
|
|
17
17
|
export type {
|
|
18
|
+
BuilderId,
|
|
19
|
+
BuilderResponse,
|
|
20
|
+
BuilderStatus,
|
|
18
21
|
EpochCommitteeResponse,
|
|
19
22
|
EpochSyncCommitteeResponse,
|
|
20
23
|
FinalityCheckpoints,
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
ForkPreElectra,
|
|
7
7
|
MAX_PAYLOAD_ATTESTATIONS,
|
|
8
8
|
PTC_SIZE,
|
|
9
|
-
SLOTS_PER_EPOCH,
|
|
10
9
|
isForkPostElectra,
|
|
11
10
|
} from "@lodestar/params";
|
|
12
11
|
import {
|
|
@@ -47,12 +46,6 @@ const SignedBLSToExecutionChangeListType = ArrayOf(ssz.capella.SignedBLSToExecut
|
|
|
47
46
|
const SyncCommitteeMessageListType = ArrayOf(ssz.altair.SyncCommitteeMessage);
|
|
48
47
|
const PayloadAttestationListType = ArrayOf(ssz.gloas.PayloadAttestation, MAX_PAYLOAD_ATTESTATIONS);
|
|
49
48
|
const PayloadAttestationMessageListType = ArrayOf(ssz.gloas.PayloadAttestationMessage, PTC_SIZE);
|
|
50
|
-
// 2 * SLOTS_PER_EPOCH max normally; getAll() may return up to 3 * SLOTS_PER_EPOCH during non-finality
|
|
51
|
-
const MAX_PROPOSER_PREFERENCES_PER_REQUEST = 3 * SLOTS_PER_EPOCH;
|
|
52
|
-
const SignedProposerPreferencesListType = ArrayOf(
|
|
53
|
-
ssz.gloas.SignedProposerPreferences,
|
|
54
|
-
MAX_PROPOSER_PREFERENCES_PER_REQUEST
|
|
55
|
-
);
|
|
56
49
|
|
|
57
50
|
type AttestationListPhase0 = ValueOf<typeof AttestationListTypePhase0>;
|
|
58
51
|
type AttestationListElectra = ValueOf<typeof AttestationListTypeElectra>;
|
|
@@ -68,7 +61,6 @@ type SignedBLSToExecutionChangeList = ValueOf<typeof SignedBLSToExecutionChangeL
|
|
|
68
61
|
type SyncCommitteeMessageList = ValueOf<typeof SyncCommitteeMessageListType>;
|
|
69
62
|
type PayloadAttestationList = ValueOf<typeof PayloadAttestationListType>;
|
|
70
63
|
type PayloadAttestationMessageList = ValueOf<typeof PayloadAttestationMessageListType>;
|
|
71
|
-
type SignedProposerPreferencesList = ValueOf<typeof SignedProposerPreferencesListType>;
|
|
72
64
|
|
|
73
65
|
export type Endpoints = {
|
|
74
66
|
/**
|
|
@@ -95,18 +87,6 @@ export type Endpoints = {
|
|
|
95
87
|
VersionMeta
|
|
96
88
|
>;
|
|
97
89
|
|
|
98
|
-
/**
|
|
99
|
-
* Get signed proposer preferences from operations pool
|
|
100
|
-
* Retrieves proposer preferences known by the node but not necessarily incorporated into any block.
|
|
101
|
-
*/
|
|
102
|
-
getPoolProposerPreferences: Endpoint<
|
|
103
|
-
"GET",
|
|
104
|
-
{slot?: Slot},
|
|
105
|
-
{query: {slot?: number}},
|
|
106
|
-
SignedProposerPreferencesList,
|
|
107
|
-
VersionMeta
|
|
108
|
-
>;
|
|
109
|
-
|
|
110
90
|
/**
|
|
111
91
|
* Get AttesterSlashings from operations pool
|
|
112
92
|
* Retrieves attester slashings known by the node but not necessarily incorporated into any block
|
|
@@ -246,18 +226,6 @@ export type Endpoints = {
|
|
|
246
226
|
EmptyResponseData,
|
|
247
227
|
EmptyMeta
|
|
248
228
|
>;
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Submit signed proposer preferences
|
|
252
|
-
* Submits signed proposer preferences to the beacon node.
|
|
253
|
-
*/
|
|
254
|
-
submitSignedProposerPreferences: Endpoint<
|
|
255
|
-
"POST",
|
|
256
|
-
{signedProposerPreferences: SignedProposerPreferencesList},
|
|
257
|
-
{body: unknown; headers: {[MetaHeader.Version]: string}},
|
|
258
|
-
EmptyResponseData,
|
|
259
|
-
EmptyMeta
|
|
260
|
-
>;
|
|
261
229
|
};
|
|
262
230
|
|
|
263
231
|
export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
|
|
@@ -288,19 +256,6 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
288
256
|
meta: VersionCodec,
|
|
289
257
|
},
|
|
290
258
|
},
|
|
291
|
-
getPoolProposerPreferences: {
|
|
292
|
-
url: "/eth/v1/beacon/pool/proposer_preferences",
|
|
293
|
-
method: "GET",
|
|
294
|
-
req: {
|
|
295
|
-
writeReq: ({slot}) => ({query: {slot}}),
|
|
296
|
-
parseReq: ({query}) => ({slot: query.slot}),
|
|
297
|
-
schema: {query: {slot: Schema.Uint}},
|
|
298
|
-
},
|
|
299
|
-
resp: {
|
|
300
|
-
data: SignedProposerPreferencesListType,
|
|
301
|
-
meta: VersionCodec,
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
259
|
getPoolAttesterSlashingsV2: {
|
|
305
260
|
url: "/eth/v2/beacon/pool/attester_slashings",
|
|
306
261
|
method: "GET",
|
|
@@ -516,32 +471,5 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
516
471
|
},
|
|
517
472
|
resp: EmptyResponseCodec,
|
|
518
473
|
},
|
|
519
|
-
submitSignedProposerPreferences: {
|
|
520
|
-
url: "/eth/v1/beacon/pool/proposer_preferences",
|
|
521
|
-
method: "POST",
|
|
522
|
-
req: {
|
|
523
|
-
writeReqJson: ({signedProposerPreferences}) => ({
|
|
524
|
-
body: SignedProposerPreferencesListType.toJson(signedProposerPreferences),
|
|
525
|
-
headers: {[MetaHeader.Version]: ForkName.gloas},
|
|
526
|
-
}),
|
|
527
|
-
parseReqJson: ({body, headers}) => {
|
|
528
|
-
toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
529
|
-
return {signedProposerPreferences: SignedProposerPreferencesListType.fromJson(body)};
|
|
530
|
-
},
|
|
531
|
-
writeReqSsz: ({signedProposerPreferences}) => ({
|
|
532
|
-
body: SignedProposerPreferencesListType.serialize(signedProposerPreferences),
|
|
533
|
-
headers: {[MetaHeader.Version]: ForkName.gloas},
|
|
534
|
-
}),
|
|
535
|
-
parseReqSsz: ({body, headers}) => {
|
|
536
|
-
toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
537
|
-
return {signedProposerPreferences: SignedProposerPreferencesListType.deserialize(body)};
|
|
538
|
-
},
|
|
539
|
-
schema: {
|
|
540
|
-
body: Schema.ObjectArray,
|
|
541
|
-
headers: {[MetaHeader.Version]: Schema.String},
|
|
542
|
-
},
|
|
543
|
-
},
|
|
544
|
-
resp: EmptyResponseCodec,
|
|
545
|
-
},
|
|
546
474
|
};
|
|
547
475
|
}
|
|
@@ -3,6 +3,7 @@ import {ChainForkConfig} from "@lodestar/config";
|
|
|
3
3
|
import {MAX_VALIDATORS_PER_COMMITTEE} from "@lodestar/params";
|
|
4
4
|
import {
|
|
5
5
|
ArrayOf,
|
|
6
|
+
BuilderStatus,
|
|
6
7
|
CommitteeIndex,
|
|
7
8
|
Epoch,
|
|
8
9
|
RootHex,
|
|
@@ -22,7 +23,7 @@ import {
|
|
|
22
23
|
ExecutionOptimisticFinalizedAndVersionCodec,
|
|
23
24
|
ExecutionOptimisticFinalizedAndVersionMeta,
|
|
24
25
|
} from "../../../utils/metadata.js";
|
|
25
|
-
import {fromValidatorIdsStr, toValidatorIdsStr} from "../../../utils/serdes.js";
|
|
26
|
+
import {fromBuilderIdsStr, fromValidatorIdsStr, toBuilderIdsStr, toValidatorIdsStr} from "../../../utils/serdes.js";
|
|
26
27
|
import {WireFormat} from "../../../utils/wireFormat.js";
|
|
27
28
|
import {RootResponse, RootResponseType} from "./block.js";
|
|
28
29
|
|
|
@@ -37,8 +38,9 @@ export type StateArgs = {
|
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
export type ValidatorId = string | number;
|
|
41
|
+
export type BuilderId = string | number;
|
|
40
42
|
|
|
41
|
-
export type {ValidatorStatus};
|
|
43
|
+
export type {BuilderStatus, ValidatorStatus};
|
|
42
44
|
|
|
43
45
|
export const RandaoResponseType = new ContainerType({
|
|
44
46
|
randao: ssz.Root,
|
|
@@ -57,6 +59,11 @@ export const ValidatorResponseType = new ContainerType({
|
|
|
57
59
|
status: new StringType<ValidatorStatus>(),
|
|
58
60
|
validator: ssz.phase0.Validator,
|
|
59
61
|
});
|
|
62
|
+
export const BuilderResponseType = new ContainerType({
|
|
63
|
+
index: ssz.BuilderIndex,
|
|
64
|
+
status: new StringType<BuilderStatus>(),
|
|
65
|
+
builder: ssz.gloas.Builder,
|
|
66
|
+
});
|
|
60
67
|
export const ValidatorIdentityType = new ContainerType(
|
|
61
68
|
{
|
|
62
69
|
index: ssz.ValidatorIndex,
|
|
@@ -84,6 +91,7 @@ export const EpochSyncCommitteeResponseType = new ContainerType(
|
|
|
84
91
|
{jsonCase: "eth2"}
|
|
85
92
|
);
|
|
86
93
|
export const ValidatorResponseListType = ArrayOf(ValidatorResponseType);
|
|
94
|
+
export const BuilderResponseListType = ArrayOf(BuilderResponseType);
|
|
87
95
|
export const ValidatorIdentitiesType = ArrayOf(ValidatorIdentityType);
|
|
88
96
|
export const EpochCommitteeResponseListType = ArrayOf(EpochCommitteeResponseType);
|
|
89
97
|
export const ValidatorBalanceListType = ArrayOf(ValidatorBalanceType);
|
|
@@ -91,11 +99,13 @@ export const ValidatorBalanceListType = ArrayOf(ValidatorBalanceType);
|
|
|
91
99
|
export type RandaoResponse = ValueOf<typeof RandaoResponseType>;
|
|
92
100
|
export type FinalityCheckpoints = ValueOf<typeof FinalityCheckpointsType>;
|
|
93
101
|
export type ValidatorResponse = ValueOf<typeof ValidatorResponseType>;
|
|
102
|
+
export type BuilderResponse = ValueOf<typeof BuilderResponseType>;
|
|
94
103
|
export type EpochCommitteeResponse = ValueOf<typeof EpochCommitteeResponseType>;
|
|
95
104
|
export type ValidatorBalance = ValueOf<typeof ValidatorBalanceType>;
|
|
96
105
|
export type EpochSyncCommitteeResponse = ValueOf<typeof EpochSyncCommitteeResponseType>;
|
|
97
106
|
|
|
98
107
|
export type ValidatorResponseList = ValueOf<typeof ValidatorResponseListType>;
|
|
108
|
+
export type BuilderResponseList = ValueOf<typeof BuilderResponseListType>;
|
|
99
109
|
export type ValidatorIdentities = ValueOf<typeof ValidatorIdentitiesType>;
|
|
100
110
|
export type EpochCommitteeResponseList = ValueOf<typeof EpochCommitteeResponseListType>;
|
|
101
111
|
export type ValidatorBalanceList = ValueOf<typeof ValidatorBalanceListType>;
|
|
@@ -204,6 +214,30 @@ export type Endpoints = {
|
|
|
204
214
|
ExecutionOptimisticAndFinalizedMeta
|
|
205
215
|
>;
|
|
206
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Get builders from state
|
|
219
|
+
*
|
|
220
|
+
* Returns filterable list of builders with their status and index.
|
|
221
|
+
*
|
|
222
|
+
* Information will be returned for all indices or public keys that match known builders. If an index or public key does not
|
|
223
|
+
* match any known builder, no information will be returned but this will not cause an error. There are no guarantees for the
|
|
224
|
+
* returned data in terms of ordering; both the index and public key are returned for each builder, and can be used to confirm
|
|
225
|
+
* for which inputs a response has been returned.
|
|
226
|
+
*
|
|
227
|
+
* Returns 400 if the requested state is prior to Gloas.
|
|
228
|
+
*/
|
|
229
|
+
getStateBuilders: Endpoint<
|
|
230
|
+
"POST",
|
|
231
|
+
StateArgs & {
|
|
232
|
+
/** Either hex encoded public key (any bytes48 with 0x prefix) or builder index */
|
|
233
|
+
builderIds?: BuilderId[];
|
|
234
|
+
statuses?: BuilderStatus[];
|
|
235
|
+
},
|
|
236
|
+
{params: {state_id: string}; body: {ids?: string[]; statuses?: BuilderStatus[]}},
|
|
237
|
+
BuilderResponseList,
|
|
238
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
239
|
+
>;
|
|
240
|
+
|
|
207
241
|
/**
|
|
208
242
|
* Get validator identities from state
|
|
209
243
|
*
|
|
@@ -489,6 +523,33 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
|
|
|
489
523
|
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
490
524
|
},
|
|
491
525
|
},
|
|
526
|
+
getStateBuilders: {
|
|
527
|
+
url: "/eth/v1/beacon/states/{state_id}/builders",
|
|
528
|
+
method: "POST",
|
|
529
|
+
req: JsonOnlyReq({
|
|
530
|
+
writeReqJson: ({stateId, builderIds, statuses}) => ({
|
|
531
|
+
params: {state_id: stateId.toString()},
|
|
532
|
+
body: {
|
|
533
|
+
ids: toBuilderIdsStr(builderIds),
|
|
534
|
+
statuses,
|
|
535
|
+
},
|
|
536
|
+
}),
|
|
537
|
+
parseReqJson: ({params, body = {}}) => ({
|
|
538
|
+
stateId: params.state_id,
|
|
539
|
+
builderIds: fromBuilderIdsStr(body.ids),
|
|
540
|
+
statuses: body.statuses ?? undefined,
|
|
541
|
+
}),
|
|
542
|
+
schema: {
|
|
543
|
+
params: {state_id: Schema.StringRequired},
|
|
544
|
+
body: Schema.Object,
|
|
545
|
+
},
|
|
546
|
+
}),
|
|
547
|
+
resp: {
|
|
548
|
+
onlySupport: WireFormat.json,
|
|
549
|
+
data: BuilderResponseListType,
|
|
550
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
551
|
+
},
|
|
552
|
+
},
|
|
492
553
|
postStateValidatorIdentities: {
|
|
493
554
|
url: "/eth/v1/beacon/states/{state_id}/validator_identities",
|
|
494
555
|
method: "POST",
|
|
@@ -110,6 +110,8 @@ export enum EventType {
|
|
|
110
110
|
executionPayloadBid = "execution_payload_bid",
|
|
111
111
|
/** The node has received a `SignedProposerPreferences` (from P2P or API) that passes gossip validation on the `proposer_preferences` topic */
|
|
112
112
|
proposerPreferences = "proposer_preferences",
|
|
113
|
+
/** The node has received a `PayloadAttestationMessage` (from P2P or API) that passes validation rules of the `payload_attestation_message` topic */
|
|
114
|
+
payloadAttestationMessage = "payload_attestation_message",
|
|
113
115
|
/** The node has executed the Fast Confirmation Rule and produced a confirmed beacon block */
|
|
114
116
|
fastConfirmation = "fast_confirmation",
|
|
115
117
|
}
|
|
@@ -137,6 +139,7 @@ export const eventTypes: {[K in EventType]: K} = {
|
|
|
137
139
|
[EventType.executionPayloadAvailable]: EventType.executionPayloadAvailable,
|
|
138
140
|
[EventType.executionPayloadBid]: EventType.executionPayloadBid,
|
|
139
141
|
[EventType.proposerPreferences]: EventType.proposerPreferences,
|
|
142
|
+
[EventType.payloadAttestationMessage]: EventType.payloadAttestationMessage,
|
|
140
143
|
[EventType.fastConfirmation]: EventType.fastConfirmation,
|
|
141
144
|
};
|
|
142
145
|
|
|
@@ -206,6 +209,7 @@ export type EventData = {
|
|
|
206
209
|
};
|
|
207
210
|
[EventType.executionPayloadBid]: {version: ForkName; data: gloas.SignedExecutionPayloadBid};
|
|
208
211
|
[EventType.proposerPreferences]: {version: ForkName; data: gloas.SignedProposerPreferences};
|
|
212
|
+
[EventType.payloadAttestationMessage]: {version: ForkName; data: gloas.PayloadAttestationMessage};
|
|
209
213
|
[EventType.fastConfirmation]: {
|
|
210
214
|
block: RootHex;
|
|
211
215
|
slot: Slot;
|
|
@@ -408,6 +412,7 @@ export function getTypeByEvent(config: ChainForkConfig): {[K in EventType]: Type
|
|
|
408
412
|
),
|
|
409
413
|
[EventType.executionPayloadBid]: WithVersion((fork) => getPostGloasForkTypes(fork).SignedExecutionPayloadBid),
|
|
410
414
|
[EventType.proposerPreferences]: WithVersion((fork) => getPostGloasForkTypes(fork).SignedProposerPreferences),
|
|
415
|
+
[EventType.payloadAttestationMessage]: WithVersion((fork) => getPostGloasForkTypes(fork).PayloadAttestationMessage),
|
|
411
416
|
[EventType.fastConfirmation]: new ContainerType(
|
|
412
417
|
{
|
|
413
418
|
block: stringType,
|
|
@@ -106,6 +106,7 @@ export enum NodeHealth {
|
|
|
106
106
|
*/
|
|
107
107
|
export enum ClientCode {
|
|
108
108
|
BU = "BU", // besu
|
|
109
|
+
CN = "CN", // caplin
|
|
109
110
|
EJ = "EJ", // ethereumJS
|
|
110
111
|
EG = "EG", // erigon
|
|
111
112
|
EX = "EX", // ethrex
|
|
@@ -114,7 +115,8 @@ export enum ClientCode {
|
|
|
114
115
|
LH = "LH", // lighthouse
|
|
115
116
|
LS = "LS", // lodestar
|
|
116
117
|
NM = "NM", // nethermind
|
|
117
|
-
NB = "NB", // nimbus
|
|
118
|
+
NB = "NB", // nimbus CL
|
|
119
|
+
NE = "NE", // nimbus EL
|
|
118
120
|
TE = "TE", // trin-execution
|
|
119
121
|
TK = "TK", // teku
|
|
120
122
|
PM = "PM", // prysm
|
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
ForkPostDeneb,
|
|
5
5
|
ForkPostGloas,
|
|
6
6
|
ForkPreDeneb,
|
|
7
|
+
MIN_SEED_LOOKAHEAD,
|
|
8
|
+
SLOTS_PER_EPOCH,
|
|
7
9
|
VALIDATOR_REGISTRY_LIMIT,
|
|
8
10
|
isForkPostDeneb,
|
|
9
11
|
isForkPostElectra,
|
|
@@ -36,6 +38,7 @@ import {
|
|
|
36
38
|
EmptyResponseCodec,
|
|
37
39
|
EmptyResponseData,
|
|
38
40
|
JsonOnlyReq,
|
|
41
|
+
WithMeta,
|
|
39
42
|
WithVersion,
|
|
40
43
|
} from "../../utils/codecs.js";
|
|
41
44
|
import {getPostBellatrixForkTypes, getPostGloasForkTypes, toForkName} from "../../utils/fork.js";
|
|
@@ -96,6 +99,10 @@ export const ProduceBlockV4MetaType = new ContainerType(
|
|
|
96
99
|
...VersionType.fields,
|
|
97
100
|
/** Consensus rewards paid to the proposer for this block, in Wei */
|
|
98
101
|
consensusBlockValue: ssz.UintBn64,
|
|
102
|
+
/** Local execution payload value when self-building, or builder bid value when committing to a bid, in Wei */
|
|
103
|
+
executionPayloadValue: ssz.UintBn64,
|
|
104
|
+
/** Specifies whether the response contains full block contents or only the beacon block */
|
|
105
|
+
executionPayloadIncluded: ssz.Boolean,
|
|
99
106
|
},
|
|
100
107
|
{jsonCase: "eth2"}
|
|
101
108
|
);
|
|
@@ -246,6 +253,10 @@ export const SignedValidatorRegistrationV1ListType = ArrayOf(
|
|
|
246
253
|
ssz.bellatrix.SignedValidatorRegistrationV1,
|
|
247
254
|
VALIDATOR_REGISTRY_LIMIT
|
|
248
255
|
);
|
|
256
|
+
export const SignedProposerPreferencesListType = ArrayOf(
|
|
257
|
+
ssz.gloas.SignedProposerPreferences,
|
|
258
|
+
(MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH
|
|
259
|
+
);
|
|
249
260
|
|
|
250
261
|
export type ValidatorIndices = ValueOf<typeof ValidatorIndicesType>;
|
|
251
262
|
export type AttesterDuty = ValueOf<typeof AttesterDutyType>;
|
|
@@ -273,6 +284,13 @@ export type SyncCommitteeSelectionList = ValueOf<typeof SyncCommitteeSelectionLi
|
|
|
273
284
|
export type LivenessResponseData = ValueOf<typeof LivenessResponseDataType>;
|
|
274
285
|
export type LivenessResponseDataList = ValueOf<typeof LivenessResponseDataListType>;
|
|
275
286
|
export type SignedValidatorRegistrationV1List = ValueOf<typeof SignedValidatorRegistrationV1ListType>;
|
|
287
|
+
export type SignedProposerPreferencesList = ValueOf<typeof SignedProposerPreferencesListType>;
|
|
288
|
+
|
|
289
|
+
// The beacon node does not return any data if there is no canonical block at the requested slot (missed slot).
|
|
290
|
+
// In this case, we receive a success response (204) which is not handled as an error. The generic response
|
|
291
|
+
// handler already checks the status code and will not attempt to parse the body, but it will return no value.
|
|
292
|
+
// It is important that this type indicates that there might be no value to ensure it is properly handled downstream.
|
|
293
|
+
export type MaybePayloadAttestationData = gloas.PayloadAttestationData | undefined;
|
|
276
294
|
|
|
277
295
|
export type Endpoints = {
|
|
278
296
|
/**
|
|
@@ -408,6 +426,12 @@ export type Endpoints = {
|
|
|
408
426
|
* Post-Gloas, proposers submit execution payload bids rather than full execution payloads,
|
|
409
427
|
* so there is no longer a concept of blinded or unblinded blocks. Builders release the payload later.
|
|
410
428
|
* This endpoint is specific to the post-Gloas forks and is not backwards compatible with previous forks.
|
|
429
|
+
*
|
|
430
|
+
* When self-building and `includePayload` is true, the response contains the full `BlockContents`
|
|
431
|
+
* (block, execution payload envelope, KZG proofs and blobs) which enables stateless envelope
|
|
432
|
+
* publishing via any beacon node. When `includePayload` is false, only the `BeaconBlock` is
|
|
433
|
+
* returned and the beacon node caches the envelope and blobs internally.
|
|
434
|
+
* When committing to a builder bid, only the `BeaconBlock` is returned in either case.
|
|
411
435
|
*/
|
|
412
436
|
produceBlockV4: Endpoint<
|
|
413
437
|
"GET",
|
|
@@ -420,6 +444,8 @@ export type Endpoints = {
|
|
|
420
444
|
graffiti?: string;
|
|
421
445
|
skipRandaoVerification?: boolean;
|
|
422
446
|
builderBoostFactor?: UintBn64;
|
|
447
|
+
/** Include execution payload envelope and blobs in the response when self-building */
|
|
448
|
+
includePayload: boolean;
|
|
423
449
|
} & Omit<ExtraProduceBlockOpts, "blindedLocal">,
|
|
424
450
|
{
|
|
425
451
|
params: {slot: number};
|
|
@@ -431,16 +457,18 @@ export type Endpoints = {
|
|
|
431
457
|
builder_selection?: string;
|
|
432
458
|
builder_boost_factor?: string;
|
|
433
459
|
strict_fee_recipient_check?: boolean;
|
|
460
|
+
include_payload: boolean;
|
|
434
461
|
};
|
|
435
462
|
},
|
|
436
|
-
BeaconBlock<ForkPostGloas>,
|
|
463
|
+
BeaconBlock<ForkPostGloas> | BlockContents<ForkPostGloas>,
|
|
437
464
|
ProduceBlockV4Meta
|
|
438
465
|
>;
|
|
439
466
|
|
|
440
467
|
/**
|
|
441
468
|
* Get execution payload envelope.
|
|
442
|
-
* Retrieves execution payload envelope for a given slot and beacon block root
|
|
443
|
-
*
|
|
469
|
+
* Retrieves the cached execution payload envelope for a given slot and beacon block root,
|
|
470
|
+
* to be signed and published via `publishExecutionPayloadEnvelope`.
|
|
471
|
+
* Used in the stateful (`includePayload=false`) local build flow.
|
|
444
472
|
*/
|
|
445
473
|
getExecutionPayloadEnvelope: Endpoint<
|
|
446
474
|
"GET",
|
|
@@ -482,8 +510,8 @@ export type Endpoints = {
|
|
|
482
510
|
/** The slot for which payload attestation data should be created */
|
|
483
511
|
slot: Slot;
|
|
484
512
|
},
|
|
485
|
-
{
|
|
486
|
-
|
|
513
|
+
{query: {slot: Slot}},
|
|
514
|
+
MaybePayloadAttestationData,
|
|
487
515
|
VersionMeta
|
|
488
516
|
>;
|
|
489
517
|
|
|
@@ -646,6 +674,20 @@ export type Endpoints = {
|
|
|
646
674
|
EmptyResponseData,
|
|
647
675
|
EmptyMeta
|
|
648
676
|
>;
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Submit signed proposer preferences
|
|
680
|
+
*
|
|
681
|
+
* Verifies given signed proposer preferences and publishes them on the `proposer_preferences`
|
|
682
|
+
* gossipsub topic. Supersedes `prepareBeaconProposer` and `registerValidator` from Gloas onwards.
|
|
683
|
+
*/
|
|
684
|
+
submitProposerPreferences: Endpoint<
|
|
685
|
+
"POST",
|
|
686
|
+
{signedProposerPreferences: SignedProposerPreferencesList},
|
|
687
|
+
{body: unknown; headers: {[MetaHeader.Version]: string}},
|
|
688
|
+
EmptyResponseData,
|
|
689
|
+
EmptyMeta
|
|
690
|
+
>;
|
|
649
691
|
};
|
|
650
692
|
|
|
651
693
|
export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
|
|
@@ -879,6 +921,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
879
921
|
builderSelection,
|
|
880
922
|
builderBoostFactor,
|
|
881
923
|
strictFeeRecipientCheck,
|
|
924
|
+
includePayload,
|
|
882
925
|
}) => ({
|
|
883
926
|
params: {slot},
|
|
884
927
|
query: {
|
|
@@ -889,6 +932,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
889
932
|
builder_selection: builderSelection,
|
|
890
933
|
builder_boost_factor: builderBoostFactor?.toString(),
|
|
891
934
|
strict_fee_recipient_check: strictFeeRecipientCheck,
|
|
935
|
+
include_payload: includePayload,
|
|
892
936
|
},
|
|
893
937
|
}),
|
|
894
938
|
parseReq: ({params, query}) => ({
|
|
@@ -900,6 +944,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
900
944
|
builderSelection: query.builder_selection as BuilderSelection,
|
|
901
945
|
builderBoostFactor: parseBuilderBoostFactor(query.builder_boost_factor),
|
|
902
946
|
strictFeeRecipientCheck: query.strict_fee_recipient_check,
|
|
947
|
+
includePayload: query.include_payload,
|
|
903
948
|
}),
|
|
904
949
|
schema: {
|
|
905
950
|
params: {slot: Schema.UintRequired},
|
|
@@ -911,21 +956,33 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
911
956
|
builder_selection: Schema.String,
|
|
912
957
|
builder_boost_factor: Schema.String,
|
|
913
958
|
strict_fee_recipient_check: Schema.Boolean,
|
|
959
|
+
include_payload: Schema.BooleanRequired,
|
|
914
960
|
},
|
|
915
961
|
},
|
|
916
962
|
},
|
|
917
963
|
resp: {
|
|
918
|
-
data:
|
|
964
|
+
data: WithMeta(
|
|
965
|
+
({version, executionPayloadIncluded}) =>
|
|
966
|
+
(executionPayloadIncluded
|
|
967
|
+
? getPostGloasForkTypes(version).BlockContents
|
|
968
|
+
: getPostGloasForkTypes(version).BeaconBlock) as Type<
|
|
969
|
+
BeaconBlock<ForkPostGloas> | BlockContents<ForkPostGloas>
|
|
970
|
+
>
|
|
971
|
+
),
|
|
919
972
|
meta: {
|
|
920
973
|
toJson: (meta) => ProduceBlockV4MetaType.toJson(meta),
|
|
921
974
|
fromJson: (val) => ProduceBlockV4MetaType.fromJson(val),
|
|
922
975
|
toHeadersObject: (meta) => ({
|
|
923
976
|
[MetaHeader.Version]: meta.version,
|
|
924
977
|
[MetaHeader.ConsensusBlockValue]: meta.consensusBlockValue.toString(),
|
|
978
|
+
[MetaHeader.ExecutionPayloadValue]: meta.executionPayloadValue.toString(),
|
|
979
|
+
[MetaHeader.ExecutionPayloadIncluded]: meta.executionPayloadIncluded.toString(),
|
|
925
980
|
}),
|
|
926
981
|
fromHeaders: (headers) => ({
|
|
927
982
|
version: toForkName(headers.getRequired(MetaHeader.Version)),
|
|
928
983
|
consensusBlockValue: BigInt(headers.getRequired(MetaHeader.ConsensusBlockValue)),
|
|
984
|
+
executionPayloadValue: BigInt(headers.getRequired(MetaHeader.ExecutionPayloadValue)),
|
|
985
|
+
executionPayloadIncluded: toBoolean(headers.getRequired(MetaHeader.ExecutionPayloadIncluded)),
|
|
929
986
|
}),
|
|
930
987
|
},
|
|
931
988
|
},
|
|
@@ -972,17 +1029,17 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
972
1029
|
},
|
|
973
1030
|
},
|
|
974
1031
|
producePayloadAttestationData: {
|
|
975
|
-
url: "/eth/v1/validator/payload_attestation_data
|
|
1032
|
+
url: "/eth/v1/validator/payload_attestation_data",
|
|
976
1033
|
method: "GET",
|
|
977
1034
|
req: {
|
|
978
|
-
writeReq: ({slot}) => ({
|
|
979
|
-
parseReq: ({
|
|
1035
|
+
writeReq: ({slot}) => ({query: {slot}}),
|
|
1036
|
+
parseReq: ({query}) => ({slot: query.slot}),
|
|
980
1037
|
schema: {
|
|
981
|
-
|
|
1038
|
+
query: {slot: Schema.UintRequired},
|
|
982
1039
|
},
|
|
983
1040
|
},
|
|
984
1041
|
resp: {
|
|
985
|
-
data: ssz.gloas.PayloadAttestationData,
|
|
1042
|
+
data: WithVersion<MaybePayloadAttestationData, VersionMeta>(() => ssz.gloas.PayloadAttestationData),
|
|
986
1043
|
meta: VersionCodec,
|
|
987
1044
|
},
|
|
988
1045
|
},
|
|
@@ -1210,6 +1267,33 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
|
|
|
1210
1267
|
requestWireFormat: WireFormat.ssz,
|
|
1211
1268
|
},
|
|
1212
1269
|
},
|
|
1270
|
+
submitProposerPreferences: {
|
|
1271
|
+
url: "/eth/v1/validator/proposer_preferences",
|
|
1272
|
+
method: "POST",
|
|
1273
|
+
req: {
|
|
1274
|
+
writeReqJson: ({signedProposerPreferences}) => ({
|
|
1275
|
+
body: SignedProposerPreferencesListType.toJson(signedProposerPreferences),
|
|
1276
|
+
headers: {[MetaHeader.Version]: config.getForkName(signedProposerPreferences[0]?.message.proposalSlot ?? 0)},
|
|
1277
|
+
}),
|
|
1278
|
+
parseReqJson: ({body, headers}) => {
|
|
1279
|
+
toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
1280
|
+
return {signedProposerPreferences: SignedProposerPreferencesListType.fromJson(body)};
|
|
1281
|
+
},
|
|
1282
|
+
writeReqSsz: ({signedProposerPreferences}) => ({
|
|
1283
|
+
body: SignedProposerPreferencesListType.serialize(signedProposerPreferences),
|
|
1284
|
+
headers: {[MetaHeader.Version]: config.getForkName(signedProposerPreferences[0]?.message.proposalSlot ?? 0)},
|
|
1285
|
+
}),
|
|
1286
|
+
parseReqSsz: ({body, headers}) => {
|
|
1287
|
+
toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
1288
|
+
return {signedProposerPreferences: SignedProposerPreferencesListType.deserialize(body)};
|
|
1289
|
+
},
|
|
1290
|
+
schema: {
|
|
1291
|
+
body: Schema.ObjectArray,
|
|
1292
|
+
headers: {[MetaHeader.Version]: Schema.String},
|
|
1293
|
+
},
|
|
1294
|
+
},
|
|
1295
|
+
resp: EmptyResponseCodec,
|
|
1296
|
+
},
|
|
1213
1297
|
};
|
|
1214
1298
|
}
|
|
1215
1299
|
|
package/src/utils/metadata.ts
CHANGED
|
@@ -74,8 +74,10 @@ export type ExecutionOptimisticAndDependentRootMeta = ValueOf<typeof ExecutionOp
|
|
|
74
74
|
|
|
75
75
|
export enum MetaHeader {
|
|
76
76
|
Version = "Eth-Consensus-Version",
|
|
77
|
+
BlobDataIncluded = "Eth-Blob-Data-Included",
|
|
77
78
|
ConsensusBlockValue = "Eth-Consensus-Block-Value",
|
|
78
79
|
ExecutionPayloadBlinded = "Eth-Execution-Payload-Blinded",
|
|
80
|
+
ExecutionPayloadIncluded = "Eth-Execution-Payload-Included",
|
|
79
81
|
ExecutionPayloadValue = "Eth-Execution-Payload-Value",
|
|
80
82
|
|
|
81
83
|
/* Lodestar-specific (non-standardized) headers */
|