@lodestar/api 1.35.0-dev.f80d2d52da → 1.35.0-dev.fcf8d024ea

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.
Files changed (180) hide show
  1. package/lib/beacon/client/beacon.d.ts.map +1 -0
  2. package/lib/beacon/client/config.d.ts.map +1 -0
  3. package/lib/beacon/client/debug.d.ts.map +1 -0
  4. package/lib/beacon/client/events.d.ts.map +1 -0
  5. package/lib/beacon/client/index.d.ts.map +1 -0
  6. package/lib/beacon/client/index.js.map +1 -1
  7. package/lib/beacon/client/lightclient.d.ts.map +1 -0
  8. package/lib/beacon/client/lodestar.d.ts.map +1 -0
  9. package/lib/beacon/client/node.d.ts.map +1 -0
  10. package/lib/beacon/client/proof.d.ts.map +1 -0
  11. package/lib/beacon/client/validator.d.ts.map +1 -0
  12. package/lib/beacon/index.d.ts +1 -1
  13. package/lib/beacon/index.d.ts.map +1 -0
  14. package/lib/beacon/index.js.map +1 -1
  15. package/lib/beacon/routes/beacon/block.d.ts.map +1 -0
  16. package/lib/beacon/routes/beacon/index.d.ts +3 -3
  17. package/lib/beacon/routes/beacon/index.d.ts.map +1 -0
  18. package/lib/beacon/routes/beacon/index.js.map +1 -1
  19. package/lib/beacon/routes/beacon/pool.d.ts +1 -1
  20. package/lib/beacon/routes/beacon/pool.d.ts.map +1 -0
  21. package/lib/beacon/routes/beacon/rewards.d.ts.map +1 -0
  22. package/lib/beacon/routes/beacon/rewards.js.map +1 -1
  23. package/lib/beacon/routes/beacon/state.d.ts +2 -2
  24. package/lib/beacon/routes/beacon/state.d.ts.map +1 -0
  25. package/lib/beacon/routes/config.d.ts +1 -1
  26. package/lib/beacon/routes/config.d.ts.map +1 -0
  27. package/lib/beacon/routes/debug.d.ts.map +1 -0
  28. package/lib/beacon/routes/events.d.ts.map +1 -0
  29. package/lib/beacon/routes/events.js.map +1 -1
  30. package/lib/beacon/routes/index.d.ts.map +1 -0
  31. package/lib/beacon/routes/index.js.map +1 -1
  32. package/lib/beacon/routes/lightclient.d.ts.map +1 -0
  33. package/lib/beacon/routes/lodestar.d.ts.map +1 -0
  34. package/lib/beacon/routes/node.d.ts.map +1 -0
  35. package/lib/beacon/routes/proof.d.ts.map +1 -0
  36. package/lib/beacon/routes/validator.d.ts +1 -1
  37. package/lib/beacon/routes/validator.d.ts.map +1 -0
  38. package/lib/beacon/server/beacon.d.ts.map +1 -0
  39. package/lib/beacon/server/config.d.ts.map +1 -0
  40. package/lib/beacon/server/debug.d.ts.map +1 -0
  41. package/lib/beacon/server/events.d.ts.map +1 -0
  42. package/lib/beacon/server/index.d.ts +1 -1
  43. package/lib/beacon/server/index.d.ts.map +1 -0
  44. package/lib/beacon/server/index.js.map +1 -1
  45. package/lib/beacon/server/lightclient.d.ts.map +1 -0
  46. package/lib/beacon/server/lodestar.d.ts.map +1 -0
  47. package/lib/beacon/server/node.d.ts.map +1 -0
  48. package/lib/beacon/server/proof.d.ts.map +1 -0
  49. package/lib/beacon/server/validator.d.ts.map +1 -0
  50. package/lib/builder/client.d.ts.map +1 -0
  51. package/lib/builder/index.d.ts.map +1 -0
  52. package/lib/builder/index.js.map +1 -1
  53. package/lib/builder/routes.d.ts.map +1 -0
  54. package/lib/builder/routes.js.map +1 -1
  55. package/lib/builder/server/index.d.ts +1 -1
  56. package/lib/builder/server/index.d.ts.map +1 -0
  57. package/lib/index.d.ts +6 -6
  58. package/lib/index.d.ts.map +1 -0
  59. package/lib/index.js +3 -3
  60. package/lib/index.js.map +1 -1
  61. package/lib/keymanager/client.d.ts.map +1 -0
  62. package/lib/keymanager/index.d.ts +2 -2
  63. package/lib/keymanager/index.d.ts.map +1 -0
  64. package/lib/keymanager/index.js +1 -2
  65. package/lib/keymanager/index.js.map +1 -1
  66. package/lib/keymanager/routes.d.ts.map +1 -0
  67. package/lib/keymanager/server/index.d.ts +1 -1
  68. package/lib/keymanager/server/index.d.ts.map +1 -0
  69. package/lib/server/index.d.ts.map +1 -0
  70. package/lib/utils/client/error.d.ts.map +1 -0
  71. package/lib/utils/client/error.js +2 -0
  72. package/lib/utils/client/error.js.map +1 -1
  73. package/lib/utils/client/eventSource.d.ts.map +1 -0
  74. package/lib/utils/client/format.d.ts.map +1 -0
  75. package/lib/utils/client/httpClient.d.ts +1 -2
  76. package/lib/utils/client/httpClient.d.ts.map +1 -0
  77. package/lib/utils/client/httpClient.js +13 -9
  78. package/lib/utils/client/httpClient.js.map +1 -1
  79. package/lib/utils/client/index.d.ts +1 -1
  80. package/lib/utils/client/index.d.ts.map +1 -0
  81. package/lib/utils/client/index.js +1 -1
  82. package/lib/utils/client/index.js.map +1 -1
  83. package/lib/utils/client/method.d.ts.map +1 -0
  84. package/lib/utils/client/metrics.d.ts.map +1 -0
  85. package/lib/utils/client/request.d.ts.map +1 -0
  86. package/lib/utils/client/response.d.ts.map +1 -0
  87. package/lib/utils/client/response.js +6 -0
  88. package/lib/utils/client/response.js.map +1 -1
  89. package/lib/utils/codecs.d.ts.map +1 -0
  90. package/lib/utils/fork.d.ts.map +1 -0
  91. package/lib/utils/headers.d.ts.map +1 -0
  92. package/lib/utils/httpStatusCode.d.ts.map +1 -0
  93. package/lib/utils/index.d.ts.map +1 -0
  94. package/lib/utils/metadata.d.ts.map +1 -0
  95. package/lib/utils/schema.d.ts.map +1 -0
  96. package/lib/utils/serdes.d.ts.map +1 -0
  97. package/lib/utils/server/error.d.ts.map +1 -0
  98. package/lib/utils/server/error.js +1 -0
  99. package/lib/utils/server/error.js.map +1 -1
  100. package/lib/utils/server/handler.d.ts.map +1 -0
  101. package/lib/utils/server/index.d.ts.map +1 -0
  102. package/lib/utils/server/method.d.ts.map +1 -0
  103. package/lib/utils/server/parser.d.ts.map +1 -0
  104. package/lib/utils/server/route.d.ts.map +1 -0
  105. package/lib/utils/server/route.js.map +1 -1
  106. package/lib/utils/types.d.ts.map +1 -0
  107. package/lib/utils/urlFormat.d.ts.map +1 -0
  108. package/lib/utils/wireFormat.d.ts.map +1 -0
  109. package/package.json +17 -11
  110. package/src/beacon/client/beacon.ts +12 -0
  111. package/src/beacon/client/config.ts +12 -0
  112. package/src/beacon/client/debug.ts +12 -0
  113. package/src/beacon/client/events.ts +69 -0
  114. package/src/beacon/client/index.ts +46 -0
  115. package/src/beacon/client/lightclient.ts +12 -0
  116. package/src/beacon/client/lodestar.ts +12 -0
  117. package/src/beacon/client/node.ts +12 -0
  118. package/src/beacon/client/proof.ts +12 -0
  119. package/src/beacon/client/validator.ts +12 -0
  120. package/src/beacon/index.ts +24 -0
  121. package/src/beacon/routes/beacon/block.ts +602 -0
  122. package/src/beacon/routes/beacon/index.ts +66 -0
  123. package/src/beacon/routes/beacon/pool.ts +503 -0
  124. package/src/beacon/routes/beacon/rewards.ts +216 -0
  125. package/src/beacon/routes/beacon/state.ts +588 -0
  126. package/src/beacon/routes/config.ts +114 -0
  127. package/src/beacon/routes/debug.ts +231 -0
  128. package/src/beacon/routes/events.ts +337 -0
  129. package/src/beacon/routes/index.ts +33 -0
  130. package/src/beacon/routes/lightclient.ts +241 -0
  131. package/src/beacon/routes/lodestar.ts +456 -0
  132. package/src/beacon/routes/node.ts +286 -0
  133. package/src/beacon/routes/proof.ts +79 -0
  134. package/src/beacon/routes/validator.ts +1014 -0
  135. package/src/beacon/server/beacon.ts +7 -0
  136. package/src/beacon/server/config.ts +7 -0
  137. package/src/beacon/server/debug.ts +7 -0
  138. package/src/beacon/server/events.ts +73 -0
  139. package/src/beacon/server/index.ts +55 -0
  140. package/src/beacon/server/lightclient.ts +7 -0
  141. package/src/beacon/server/lodestar.ts +7 -0
  142. package/src/beacon/server/node.ts +7 -0
  143. package/src/beacon/server/proof.ts +7 -0
  144. package/src/beacon/server/validator.ts +7 -0
  145. package/src/builder/client.ts +9 -0
  146. package/src/builder/index.ts +26 -0
  147. package/src/builder/routes.ts +227 -0
  148. package/src/builder/server/index.ts +19 -0
  149. package/src/index.ts +19 -0
  150. package/src/keymanager/client.ts +9 -0
  151. package/src/keymanager/index.ts +39 -0
  152. package/src/keymanager/routes.ts +699 -0
  153. package/src/keymanager/server/index.ts +19 -0
  154. package/src/server/index.ts +2 -0
  155. package/src/utils/client/error.ts +10 -0
  156. package/src/utils/client/eventSource.ts +7 -0
  157. package/src/utils/client/format.ts +22 -0
  158. package/src/utils/client/httpClient.ts +444 -0
  159. package/src/utils/client/index.ts +6 -0
  160. package/src/utils/client/method.ts +50 -0
  161. package/src/utils/client/metrics.ts +9 -0
  162. package/src/utils/client/request.ts +113 -0
  163. package/src/utils/client/response.ts +205 -0
  164. package/src/utils/codecs.ts +143 -0
  165. package/src/utils/fork.ts +44 -0
  166. package/src/utils/headers.ts +173 -0
  167. package/src/utils/httpStatusCode.ts +392 -0
  168. package/src/utils/index.ts +3 -0
  169. package/src/utils/metadata.ts +170 -0
  170. package/src/utils/schema.ts +141 -0
  171. package/src/utils/serdes.ts +120 -0
  172. package/src/utils/server/error.ts +9 -0
  173. package/src/utils/server/handler.ts +149 -0
  174. package/src/utils/server/index.ts +5 -0
  175. package/src/utils/server/method.ts +38 -0
  176. package/src/utils/server/parser.ts +15 -0
  177. package/src/utils/server/route.ts +45 -0
  178. package/src/utils/types.ts +161 -0
  179. package/src/utils/urlFormat.ts +112 -0
  180. package/src/utils/wireFormat.ts +24 -0
@@ -0,0 +1,241 @@
1
+ import {ListCompositeType, ValueOf} from "@chainsafe/ssz";
2
+ import {BeaconConfig, ChainForkConfig, createBeaconConfig} from "@lodestar/config";
3
+ import {NetworkName, genesisData} from "@lodestar/config/networks";
4
+ import {ForkName, SLOTS_PER_EPOCH, ZERO_HASH} from "@lodestar/params";
5
+ import {
6
+ LightClientBootstrap,
7
+ LightClientFinalityUpdate,
8
+ LightClientOptimisticUpdate,
9
+ LightClientUpdate,
10
+ SyncPeriod,
11
+ ssz,
12
+ } from "@lodestar/types";
13
+ import {fromHex} from "@lodestar/utils";
14
+ import {
15
+ EmptyArgs,
16
+ EmptyMeta,
17
+ EmptyMetaCodec,
18
+ EmptyRequest,
19
+ EmptyRequestCodec,
20
+ WithVersion,
21
+ } from "../../utils/codecs.js";
22
+ import {getPostAltairForkTypes, toForkName} from "../../utils/fork.js";
23
+ import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js";
24
+ import {MetaHeader, VersionCodec, VersionMeta} from "../../utils/metadata.js";
25
+
26
+ export const HashListType = new ListCompositeType(ssz.Root, 10000);
27
+ export type HashList = ValueOf<typeof HashListType>;
28
+
29
+ export type Endpoints = {
30
+ /**
31
+ * Returns an array of best updates given a `startPeriod` and `count` number of sync committee period to return.
32
+ * Best is defined by (in order of priority):
33
+ * - Is finalized update
34
+ * - Has most bits
35
+ * - Oldest update
36
+ */
37
+ getLightClientUpdatesByRange: Endpoint<
38
+ "GET",
39
+ {startPeriod: SyncPeriod; count: number},
40
+ {query: {start_period: number; count: number}},
41
+ LightClientUpdate[],
42
+ {versions: ForkName[]}
43
+ >;
44
+
45
+ /**
46
+ * Returns the latest optimistic head update available. Clients should use the SSE type `light_client_optimistic_update`
47
+ * unless to get the very first head update after syncing, or if SSE are not supported by the server.
48
+ */
49
+ getLightClientOptimisticUpdate: Endpoint<
50
+ // ⏎
51
+ "GET",
52
+ EmptyArgs,
53
+ EmptyRequest,
54
+ LightClientOptimisticUpdate,
55
+ VersionMeta
56
+ >;
57
+
58
+ getLightClientFinalityUpdate: Endpoint<
59
+ // ⏎
60
+ "GET",
61
+ EmptyArgs,
62
+ EmptyRequest,
63
+ LightClientFinalityUpdate,
64
+ VersionMeta
65
+ >;
66
+
67
+ /**
68
+ * Fetch a bootstrapping state with a proof to a trusted block root.
69
+ * The trusted block root should be fetched with similar means to a weak subjectivity checkpoint.
70
+ * Only block roots for checkpoints are guaranteed to be available.
71
+ */
72
+ getLightClientBootstrap: Endpoint<
73
+ "GET",
74
+ {blockRoot: string},
75
+ {params: {block_root: string}},
76
+ LightClientBootstrap,
77
+ VersionMeta
78
+ >;
79
+
80
+ /**
81
+ * Returns an array of sync committee hashes based on the provided period and count
82
+ */
83
+ getLightClientCommitteeRoot: Endpoint<
84
+ "GET",
85
+ {startPeriod: SyncPeriod; count: number},
86
+ {query: {start_period: number; count: number}},
87
+ HashList,
88
+ EmptyMeta
89
+ >;
90
+ };
91
+
92
+ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
93
+ // Cache config so fork digests don't need to be recomputed
94
+ let beaconConfig: BeaconConfig | undefined;
95
+
96
+ const cachedBeaconConfig = (): BeaconConfig => {
97
+ if (beaconConfig === undefined) {
98
+ const genesisValidatorsRoot = genesisData[config.CONFIG_NAME as NetworkName]?.genesisValidatorsRoot;
99
+ beaconConfig = createBeaconConfig(config, genesisValidatorsRoot ? fromHex(genesisValidatorsRoot) : ZERO_HASH);
100
+ }
101
+ return beaconConfig;
102
+ };
103
+
104
+ return {
105
+ getLightClientUpdatesByRange: {
106
+ url: "/eth/v1/beacon/light_client/updates",
107
+ method: "GET",
108
+ req: {
109
+ writeReq: ({startPeriod, count}) => ({query: {start_period: startPeriod, count}}),
110
+ parseReq: ({query}) => ({startPeriod: query.start_period, count: query.count}),
111
+ schema: {query: {start_period: Schema.UintRequired, count: Schema.UintRequired}},
112
+ },
113
+ resp: {
114
+ data: {
115
+ toJson: (data, meta) => {
116
+ const json: unknown[] = [];
117
+ for (const [i, update] of data.entries()) {
118
+ json.push(getPostAltairForkTypes(meta.versions[i]).LightClientUpdate.toJson(update));
119
+ }
120
+ return json;
121
+ },
122
+ fromJson: (data, meta) => {
123
+ const updates = data as unknown[];
124
+ const value: LightClientUpdate[] = [];
125
+ for (let i = 0; i < updates.length; i++) {
126
+ const version = meta.versions[i];
127
+ value.push(getPostAltairForkTypes(version).LightClientUpdate.fromJson(updates[i]));
128
+ }
129
+ return value;
130
+ },
131
+ serialize: (data, meta) => {
132
+ const chunks: Uint8Array[] = [];
133
+ for (const [i, update] of data.entries()) {
134
+ const version = meta.versions[i];
135
+ const config = cachedBeaconConfig();
136
+ const epoch = Math.floor(update.attestedHeader.beacon.slot / SLOTS_PER_EPOCH);
137
+ const forkDigest = config.forkBoundary2ForkDigest(config.getForkBoundaryAtEpoch(epoch));
138
+ const serialized = getPostAltairForkTypes(version).LightClientUpdate.serialize(update);
139
+ const length = ssz.UintNum64.serialize(4 + serialized.length);
140
+ chunks.push(length, forkDigest, serialized);
141
+ }
142
+ return Buffer.concat(chunks);
143
+ },
144
+ deserialize: (data) => {
145
+ let offset = 0;
146
+ const updates: LightClientUpdate[] = [];
147
+ while (offset < data.length) {
148
+ const length = ssz.UintNum64.deserialize(data.subarray(offset, offset + 8));
149
+ const forkDigest = ssz.ForkDigest.deserialize(data.subarray(offset + 8, offset + 12));
150
+ const {fork: version} = cachedBeaconConfig().forkDigest2ForkBoundary(forkDigest);
151
+ updates.push(
152
+ getPostAltairForkTypes(version).LightClientUpdate.deserialize(
153
+ data.subarray(offset + 12, offset + 8 + length)
154
+ )
155
+ );
156
+ offset += 8 + length;
157
+ }
158
+ return updates;
159
+ },
160
+ },
161
+ meta: {
162
+ toJson: (meta) => meta,
163
+ fromJson: (val) => val as {versions: ForkName[]},
164
+ toHeadersObject: (meta) => ({
165
+ [MetaHeader.Version]: meta.versions.join(","),
166
+ }),
167
+ fromHeaders: (headers) => {
168
+ const versions = headers.getOrDefault(MetaHeader.Version, "");
169
+ return {versions: versions === "" ? [] : (versions.split(",") as ForkName[])};
170
+ },
171
+ },
172
+ transform: {
173
+ toResponse: (data, meta) => {
174
+ const updates = data as unknown[];
175
+ const resp: unknown[] = [];
176
+ for (let i = 0; i < updates.length; i++) {
177
+ resp.push({data: updates[i], version: (meta as {versions: string[]}).versions[i]});
178
+ }
179
+ return resp;
180
+ },
181
+ fromResponse: (resp) => {
182
+ if (!Array.isArray(resp)) {
183
+ throw Error("JSON is not an array");
184
+ }
185
+ const updates: LightClientUpdate[] = [];
186
+ const meta: {versions: ForkName[]} = {versions: []};
187
+ for (const {data, version} of resp as {data: LightClientUpdate; version: string}[]) {
188
+ updates.push(data);
189
+ meta.versions.push(toForkName(version));
190
+ }
191
+ return {data: updates, meta};
192
+ },
193
+ },
194
+ },
195
+ },
196
+ getLightClientOptimisticUpdate: {
197
+ url: "/eth/v1/beacon/light_client/optimistic_update",
198
+ method: "GET",
199
+ req: EmptyRequestCodec,
200
+ resp: {
201
+ data: WithVersion((fork) => getPostAltairForkTypes(fork).LightClientOptimisticUpdate),
202
+ meta: VersionCodec,
203
+ },
204
+ },
205
+ getLightClientFinalityUpdate: {
206
+ url: "/eth/v1/beacon/light_client/finality_update",
207
+ method: "GET",
208
+ req: EmptyRequestCodec,
209
+ resp: {
210
+ data: WithVersion((fork) => getPostAltairForkTypes(fork).LightClientFinalityUpdate),
211
+ meta: VersionCodec,
212
+ },
213
+ },
214
+ getLightClientBootstrap: {
215
+ url: "/eth/v1/beacon/light_client/bootstrap/{block_root}",
216
+ method: "GET",
217
+ req: {
218
+ writeReq: ({blockRoot}) => ({params: {block_root: blockRoot}}),
219
+ parseReq: ({params}) => ({blockRoot: params.block_root}),
220
+ schema: {params: {block_root: Schema.StringRequired}},
221
+ },
222
+ resp: {
223
+ data: WithVersion((fork) => getPostAltairForkTypes(fork).LightClientBootstrap),
224
+ meta: VersionCodec,
225
+ },
226
+ },
227
+ getLightClientCommitteeRoot: {
228
+ url: "/eth/v0/beacon/light_client/committee_root",
229
+ method: "GET",
230
+ req: {
231
+ writeReq: ({startPeriod, count}) => ({query: {start_period: startPeriod, count}}),
232
+ parseReq: ({query}) => ({startPeriod: query.start_period, count: query.count}),
233
+ schema: {query: {start_period: Schema.UintRequired, count: Schema.UintRequired}},
234
+ },
235
+ resp: {
236
+ data: HashListType,
237
+ meta: EmptyMetaCodec,
238
+ },
239
+ },
240
+ };
241
+ }
@@ -0,0 +1,456 @@
1
+ import {ContainerType, ValueOf} from "@chainsafe/ssz";
2
+ import {ChainForkConfig} from "@lodestar/config";
3
+ import {Epoch, RootHex, Slot, ssz} from "@lodestar/types";
4
+ import {
5
+ ArrayOf,
6
+ EmptyArgs,
7
+ EmptyMeta,
8
+ EmptyRequest,
9
+ EmptyRequestCodec,
10
+ EmptyResponseCodec,
11
+ EmptyResponseData,
12
+ JsonOnlyResponseCodec,
13
+ } from "../../utils/codecs.js";
14
+ import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js";
15
+ import {
16
+ ExecutionOptimisticFinalizedAndVersionCodec,
17
+ ExecutionOptimisticFinalizedAndVersionMeta,
18
+ } from "../../utils/metadata.js";
19
+ import {StateArgs} from "./beacon/state.js";
20
+ import {FilterGetPeers, NodePeer, PeerDirection, PeerState} from "./node.js";
21
+
22
+ export type SyncChainDebugState = {
23
+ targetRoot: string | null;
24
+ targetSlot: number | null;
25
+ syncType: string;
26
+ status: string;
27
+ startEpoch: number;
28
+ peers: number;
29
+ // biome-ignore lint/suspicious/noExplicitAny: We need to use `any` type here
30
+ batches: any[];
31
+ };
32
+
33
+ export type GossipQueueItem = {
34
+ topic: unknown;
35
+ propagationSource: string;
36
+ data: Uint8Array;
37
+ addedTimeMs: number;
38
+ seenTimestampSec: number;
39
+ };
40
+
41
+ export type PeerScoreStat = {
42
+ peerId: string;
43
+ lodestarScore: number;
44
+ gossipScore: number;
45
+ ignoreNegativeGossipScore: boolean;
46
+ score: number;
47
+ lastUpdate: number;
48
+ };
49
+
50
+ export type GossipPeerScoreStat = {
51
+ peerId: string;
52
+ // + Other un-typed options
53
+ };
54
+
55
+ export type RegenQueueItem = {
56
+ key: string;
57
+ args: unknown;
58
+ addedTimeMs: number;
59
+ };
60
+
61
+ export type BlockProcessorQueueItem = {
62
+ blockSlots: Slot[];
63
+ jobOpts: Record<string, string | number | boolean | undefined>;
64
+ addedTimeMs: number;
65
+ };
66
+
67
+ export type StateCacheItem = {
68
+ slot: Slot;
69
+ root: RootHex;
70
+ /** Total number of reads */
71
+ reads: number;
72
+ /** Unix timestamp (ms) of the last read */
73
+ lastRead: number;
74
+ checkpointState: boolean;
75
+ };
76
+
77
+ export type LodestarNodePeer = NodePeer & {
78
+ agentVersion: string;
79
+ status: unknown | null;
80
+ metadata: unknown | null;
81
+ agentClient: string;
82
+ lastReceivedMsgUnixTsMs: number;
83
+ lastStatusUnixTsMs: number;
84
+ connectedUnixTsMs: number;
85
+ };
86
+
87
+ export type BlacklistedBlock = {root: RootHex; slot: Slot | null};
88
+
89
+ export type LodestarThreadType = "main" | "network" | "discv5";
90
+
91
+ const HistoricalSummariesResponseType = new ContainerType(
92
+ {
93
+ slot: ssz.Slot,
94
+ historicalSummaries: ssz.capella.HistoricalSummaries,
95
+ proof: ArrayOf(ssz.Bytes8),
96
+ },
97
+ {jsonCase: "eth2"}
98
+ );
99
+
100
+ export type HistoricalSummariesResponse = ValueOf<typeof HistoricalSummariesResponseType>;
101
+
102
+ export type Endpoints = {
103
+ /** Trigger to write a heapdump to disk at `dirpath`. May take > 1min */
104
+ writeHeapdump: Endpoint<
105
+ "POST",
106
+ {thread?: LodestarThreadType; dirpath?: string},
107
+ {query: {thread?: LodestarThreadType; dirpath?: string}},
108
+ {filepath: string},
109
+ EmptyMeta
110
+ >;
111
+ /** Trigger to write 10m network thread profile to disk */
112
+ writeProfile: Endpoint<
113
+ "POST",
114
+ {
115
+ thread?: LodestarThreadType;
116
+ duration?: number;
117
+ dirpath?: string;
118
+ },
119
+ {query: {thread?: LodestarThreadType; duration?: number; dirpath?: string}},
120
+ {filepath: string},
121
+ EmptyMeta
122
+ >;
123
+ /** TODO: description */
124
+ getLatestWeakSubjectivityCheckpointEpoch: Endpoint<
125
+ // ⏎
126
+ "GET",
127
+ EmptyArgs,
128
+ EmptyRequest,
129
+ Epoch,
130
+ EmptyMeta
131
+ >;
132
+ /** TODO: description */
133
+ getSyncChainsDebugState: Endpoint<
134
+ // ⏎
135
+ "GET",
136
+ EmptyArgs,
137
+ EmptyRequest,
138
+ SyncChainDebugState[],
139
+ EmptyMeta
140
+ >;
141
+ /** Dump all items in a gossip queue, by gossipType */
142
+ getGossipQueueItems: Endpoint<
143
+ // ⏎
144
+ "GET",
145
+ {gossipType: string},
146
+ {params: {gossipType: string}},
147
+ unknown[],
148
+ EmptyMeta
149
+ >;
150
+ /** Dump all items in the regen queue */
151
+ getRegenQueueItems: Endpoint<
152
+ // ⏎
153
+ "GET",
154
+ EmptyArgs,
155
+ EmptyRequest,
156
+ RegenQueueItem[],
157
+ EmptyMeta
158
+ >;
159
+ /** Dump all items in the block processor queue */
160
+ getBlockProcessorQueueItems: Endpoint<
161
+ // ⏎
162
+ "GET",
163
+ EmptyArgs,
164
+ EmptyRequest,
165
+ BlockProcessorQueueItem[],
166
+ EmptyMeta
167
+ >;
168
+ /** Dump a summary of the states in the block state cache and checkpoint state cache */
169
+ getStateCacheItems: Endpoint<
170
+ // ⏎
171
+ "GET",
172
+ EmptyArgs,
173
+ EmptyRequest,
174
+ StateCacheItem[],
175
+ EmptyMeta
176
+ >;
177
+ /** Dump peer gossip stats by peer */
178
+ getGossipPeerScoreStats: Endpoint<
179
+ // ⏎
180
+ "GET",
181
+ EmptyArgs,
182
+ EmptyRequest,
183
+ GossipPeerScoreStat[],
184
+ EmptyMeta
185
+ >;
186
+ /** Dump lodestar score stats by peer */
187
+ getLodestarPeerScoreStats: Endpoint<
188
+ // ⏎
189
+ "GET",
190
+ EmptyArgs,
191
+ EmptyRequest,
192
+ PeerScoreStat[],
193
+ EmptyMeta
194
+ >;
195
+ /** Run GC with `global.gc()` */
196
+ runGC: Endpoint<
197
+ // ⏎
198
+ "POST",
199
+ EmptyArgs,
200
+ EmptyRequest,
201
+ EmptyResponseData,
202
+ EmptyMeta
203
+ >;
204
+ /** Drop all states in the state cache */
205
+ dropStateCache: Endpoint<
206
+ // ⏎
207
+ "POST",
208
+ EmptyArgs,
209
+ EmptyRequest,
210
+ EmptyResponseData,
211
+ EmptyMeta
212
+ >;
213
+
214
+ /** Connect to peer at this multiaddress */
215
+ connectPeer: Endpoint<
216
+ // ⏎
217
+ "POST",
218
+ {peerId: string; multiaddrs: string[]},
219
+ {query: {peerId: string; multiaddr: string[]}},
220
+ EmptyResponseData,
221
+ EmptyMeta
222
+ >;
223
+ /** Disconnect peer */
224
+ disconnectPeer: Endpoint<
225
+ // ⏎
226
+ "POST",
227
+ {peerId: string},
228
+ {query: {peerId: string}},
229
+ EmptyResponseData,
230
+ EmptyMeta
231
+ >;
232
+ /** Same to node api with new fields */
233
+ getPeers: Endpoint<
234
+ "GET",
235
+ FilterGetPeers,
236
+ {query: {state?: PeerState[]; direction?: PeerDirection[]}},
237
+ LodestarNodePeer[],
238
+ {count: number}
239
+ >;
240
+
241
+ /** Returns root/slot of blacklisted blocks */
242
+ getBlacklistedBlocks: Endpoint<
243
+ // ⏎
244
+ "GET",
245
+ EmptyArgs,
246
+ EmptyRequest,
247
+ BlacklistedBlock[],
248
+ EmptyMeta
249
+ >;
250
+
251
+ /** Returns historical summaries and proof for a given state ID */
252
+ getHistoricalSummaries: Endpoint<
253
+ // ⏎
254
+ "GET",
255
+ StateArgs,
256
+ {params: {state_id: string}},
257
+ HistoricalSummariesResponse,
258
+ ExecutionOptimisticFinalizedAndVersionMeta
259
+ >;
260
+
261
+ /** Dump Discv5 Kad values */
262
+ discv5GetKadValues: Endpoint<
263
+ // ⏎
264
+ "GET",
265
+ EmptyArgs,
266
+ EmptyRequest,
267
+ string[],
268
+ EmptyMeta
269
+ >;
270
+
271
+ /**
272
+ * Dump level-db entry keys for a given Bucket declared in code, or for all buckets.
273
+ */
274
+ dumpDbBucketKeys: Endpoint<
275
+ "GET",
276
+ {
277
+ /** Must be the string name of a bucket entry: `allForks_blockArchive` */
278
+ bucket: string;
279
+ },
280
+ {params: {bucket: string}},
281
+ string[],
282
+ EmptyMeta
283
+ >;
284
+
285
+ /** Return all entries in the StateArchive index with bucket index_stateArchiveRootIndex */
286
+ dumpDbStateIndex: Endpoint<
287
+ // ⏎
288
+ "GET",
289
+ EmptyArgs,
290
+ EmptyRequest,
291
+ {root: RootHex; slot: Slot}[],
292
+ EmptyMeta
293
+ >;
294
+ };
295
+
296
+ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpoints> {
297
+ return {
298
+ writeHeapdump: {
299
+ url: "/eth/v1/lodestar/write_heapdump",
300
+ method: "POST",
301
+ req: {
302
+ writeReq: ({thread, dirpath}) => ({query: {thread, dirpath}}),
303
+ parseReq: ({query}) => ({thread: query.thread, dirpath: query.dirpath}),
304
+ schema: {query: {thread: Schema.String, dirpath: Schema.String}},
305
+ },
306
+ resp: JsonOnlyResponseCodec,
307
+ },
308
+ writeProfile: {
309
+ url: "/eth/v1/lodestar/write_profile",
310
+ method: "POST",
311
+ req: {
312
+ writeReq: ({thread, duration, dirpath}) => ({query: {thread, duration, dirpath}}),
313
+ parseReq: ({query}) => ({thread: query.thread, duration: query.duration, dirpath: query.dirpath}),
314
+ schema: {query: {thread: Schema.String, duration: Schema.Uint, dirpath: Schema.String}},
315
+ },
316
+ resp: JsonOnlyResponseCodec,
317
+ },
318
+ getLatestWeakSubjectivityCheckpointEpoch: {
319
+ url: "/eth/v1/lodestar/ws_epoch",
320
+ method: "GET",
321
+ req: EmptyRequestCodec,
322
+ resp: JsonOnlyResponseCodec,
323
+ },
324
+ getSyncChainsDebugState: {
325
+ url: "/eth/v1/lodestar/sync_chains_debug_state",
326
+ method: "GET",
327
+ req: EmptyRequestCodec,
328
+ resp: JsonOnlyResponseCodec,
329
+ },
330
+ getGossipQueueItems: {
331
+ url: "/eth/v1/lodestar/gossip_queue_items/:gossipType",
332
+ method: "GET",
333
+ req: {
334
+ writeReq: ({gossipType}) => ({params: {gossipType}}),
335
+ parseReq: ({params}) => ({gossipType: params.gossipType}),
336
+ schema: {params: {gossipType: Schema.StringRequired}},
337
+ },
338
+ resp: JsonOnlyResponseCodec,
339
+ },
340
+ getRegenQueueItems: {
341
+ url: "/eth/v1/lodestar/regen_queue_items",
342
+ method: "GET",
343
+ req: EmptyRequestCodec,
344
+ resp: JsonOnlyResponseCodec,
345
+ },
346
+ getBlockProcessorQueueItems: {
347
+ url: "/eth/v1/lodestar/block_processor_queue_items",
348
+ method: "GET",
349
+ req: EmptyRequestCodec,
350
+ resp: JsonOnlyResponseCodec,
351
+ },
352
+ getStateCacheItems: {
353
+ url: "/eth/v1/lodestar/state_cache_items",
354
+ method: "GET",
355
+ req: EmptyRequestCodec,
356
+ resp: JsonOnlyResponseCodec,
357
+ },
358
+ getGossipPeerScoreStats: {
359
+ url: "/eth/v1/lodestar/gossip_peer_score_stats",
360
+ method: "GET",
361
+ req: EmptyRequestCodec,
362
+ resp: JsonOnlyResponseCodec,
363
+ },
364
+ getLodestarPeerScoreStats: {
365
+ url: "/eth/v1/lodestar/lodestar_peer_score_stats",
366
+ method: "GET",
367
+ req: EmptyRequestCodec,
368
+ resp: JsonOnlyResponseCodec,
369
+ },
370
+ runGC: {
371
+ url: "/eth/v1/lodestar/gc",
372
+ method: "POST",
373
+ req: EmptyRequestCodec,
374
+ resp: EmptyResponseCodec,
375
+ },
376
+ dropStateCache: {
377
+ url: "/eth/v1/lodestar/drop_state_cache",
378
+ method: "POST",
379
+ req: EmptyRequestCodec,
380
+ resp: EmptyResponseCodec,
381
+ },
382
+ connectPeer: {
383
+ url: "/eth/v1/lodestar/connect_peer",
384
+ method: "POST",
385
+ req: {
386
+ writeReq: ({peerId, multiaddrs}) => ({query: {peerId, multiaddr: multiaddrs}}),
387
+ parseReq: ({query}) => ({peerId: query.peerId, multiaddrs: query.multiaddr}),
388
+ schema: {query: {peerId: Schema.StringRequired, multiaddr: Schema.StringArray}},
389
+ },
390
+ resp: EmptyResponseCodec,
391
+ },
392
+ disconnectPeer: {
393
+ url: "/eth/v1/lodestar/disconnect_peer",
394
+ method: "POST",
395
+ req: {
396
+ writeReq: ({peerId}) => ({query: {peerId}}),
397
+ parseReq: ({query}) => ({peerId: query.peerId}),
398
+ schema: {query: {peerId: Schema.StringRequired}},
399
+ },
400
+ resp: EmptyResponseCodec,
401
+ },
402
+ getPeers: {
403
+ url: "/eth/v1/lodestar/peers",
404
+ method: "GET",
405
+ req: {
406
+ writeReq: ({state, direction}) => ({query: {state, direction}}),
407
+ parseReq: ({query}) => ({state: query.state, direction: query.direction}),
408
+ schema: {query: {state: Schema.StringArray, direction: Schema.StringArray}},
409
+ },
410
+ resp: JsonOnlyResponseCodec,
411
+ },
412
+ getBlacklistedBlocks: {
413
+ url: "/eth/v1/lodestar/blacklisted_blocks",
414
+ method: "GET",
415
+ req: EmptyRequestCodec,
416
+ resp: JsonOnlyResponseCodec,
417
+ },
418
+ getHistoricalSummaries: {
419
+ url: "/eth/v1/lodestar/states/{state_id}/historical_summaries",
420
+ method: "GET",
421
+ req: {
422
+ writeReq: ({stateId}) => ({params: {state_id: stateId.toString()}}),
423
+ parseReq: ({params}) => ({stateId: params.state_id}),
424
+ schema: {
425
+ params: {state_id: Schema.StringRequired},
426
+ },
427
+ },
428
+ resp: {
429
+ data: HistoricalSummariesResponseType,
430
+ meta: ExecutionOptimisticFinalizedAndVersionCodec,
431
+ },
432
+ },
433
+ discv5GetKadValues: {
434
+ url: "/eth/v1/debug/discv5_kad_values",
435
+ method: "GET",
436
+ req: EmptyRequestCodec,
437
+ resp: JsonOnlyResponseCodec,
438
+ },
439
+ dumpDbBucketKeys: {
440
+ url: "/eth/v1/debug/dump_db_bucket_keys/:bucket",
441
+ method: "GET",
442
+ req: {
443
+ writeReq: ({bucket}) => ({params: {bucket}}),
444
+ parseReq: ({params}) => ({bucket: params.bucket}),
445
+ schema: {params: {bucket: Schema.String}},
446
+ },
447
+ resp: JsonOnlyResponseCodec,
448
+ },
449
+ dumpDbStateIndex: {
450
+ url: "/eth/v1/debug/dump_db_state_index",
451
+ method: "GET",
452
+ req: EmptyRequestCodec,
453
+ resp: JsonOnlyResponseCodec,
454
+ },
455
+ };
456
+ }