From 51aea55f6a8b09f6334b37b0e45e377890755543 Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Thu, 12 Feb 2026 14:25:31 +1000 Subject: [PATCH 1/8] feat: add Node Resources tab to slot detail page Add CPU utilization visualization to the slot detail page, powered by observoor eBPF agent data via the new fct_node_cpu_utilization model. Features: - Per-node CL/EL CPU utilization chart (0-12s slot window) - Aggregate view (mean/min/max toggle) and single-node detailed view - Normalized system utilization (sys mean/min/max) and hottest single core - EIP-7870 reference nodes filter toggle - Block arrival time overlay (markLines) - URL-backed state for node selection, metric, and filter --- src/api/@tanstack/react-query.gen.ts | 314 ++- src/api/client/client.gen.ts | 8 +- src/api/index.ts | 90 +- src/api/sdk.gen.ts | 244 +- src/api/types.gen.ts | 2166 ++++++++++++++- src/api/zod.gen.ts | 2419 +++++++++++++++-- src/pages/ethereum/slots/DetailPage.tsx | 11 + .../NodeResources/CpuUtilizationChart.tsx | 317 +++ .../NodeResources/NodeResourcesPanel.tsx | 210 ++ .../components/NodeResources/NodeSelector.tsx | 45 + .../slots/components/NodeResources/index.ts | 1 + .../slots/hooks/useSlotNodeResources/index.ts | 2 + .../useSlotNodeResources.ts | 38 + src/routes/ethereum/slots/$slot.tsx | 5 +- 14 files changed, 5491 insertions(+), 379 deletions(-) create mode 100644 src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx create mode 100644 src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx create mode 100644 src/pages/ethereum/slots/components/NodeResources/NodeSelector.tsx create mode 100644 src/pages/ethereum/slots/components/NodeResources/index.ts create mode 100644 src/pages/ethereum/slots/hooks/useSlotNodeResources/index.ts create mode 100644 src/pages/ethereum/slots/hooks/useSlotNodeResources/useSlotNodeResources.ts diff --git a/src/api/@tanstack/react-query.gen.ts b/src/api/@tanstack/react-query.gen.ts index 7dc5820fb..d588ae456 100644 --- a/src/api/@tanstack/react-query.gen.ts +++ b/src/api/@tanstack/react-query.gen.ts @@ -184,6 +184,8 @@ import { fctMissedSlotRateHourlyServiceList, fctNodeActiveLast24hServiceGet, fctNodeActiveLast24hServiceList, + fctNodeCpuUtilizationServiceGet, + fctNodeCpuUtilizationServiceList, fctOpcodeGasByOpcodeDailyServiceGet, fctOpcodeGasByOpcodeDailyServiceList, fctOpcodeGasByOpcodeHourlyServiceGet, @@ -260,6 +262,10 @@ import { intBlockOpcodeGasServiceList, intBlockProposerCanonicalServiceGet, intBlockProposerCanonicalServiceList, + intContractCreationServiceGet, + intContractCreationServiceList, + intContractSelfdestructServiceGet, + intContractSelfdestructServiceList, intContractStorageExpiry12mServiceGet, intContractStorageExpiry12mServiceList, intContractStorageExpiry18mServiceGet, @@ -300,12 +306,14 @@ import { intCustodyProbeServiceList, intEngineGetBlobsServiceGet, intEngineGetBlobsServiceList, - intEngineNewPayloadFastestServiceGet, - intEngineNewPayloadFastestServiceList, + intEngineNewPayloadFastestExecutionByNodeClassServiceGet, + intEngineNewPayloadFastestExecutionByNodeClassServiceList, intEngineNewPayloadServiceGet, intEngineNewPayloadServiceList, intExecutionBlockByDateServiceGet, intExecutionBlockByDateServiceList, + intStorageSelfdestructDiffsServiceGet, + intStorageSelfdestructDiffsServiceList, intStorageSlotDiffByAddressSlotServiceGet, intStorageSlotDiffByAddressSlotServiceList, intStorageSlotDiffServiceGet, @@ -895,6 +903,12 @@ import type { FctNodeActiveLast24hServiceListData, FctNodeActiveLast24hServiceListError, FctNodeActiveLast24hServiceListResponse, + FctNodeCpuUtilizationServiceGetData, + FctNodeCpuUtilizationServiceGetError, + FctNodeCpuUtilizationServiceGetResponse, + FctNodeCpuUtilizationServiceListData, + FctNodeCpuUtilizationServiceListError, + FctNodeCpuUtilizationServiceListResponse, FctOpcodeGasByOpcodeDailyServiceGetData, FctOpcodeGasByOpcodeDailyServiceGetError, FctOpcodeGasByOpcodeDailyServiceGetResponse, @@ -1123,6 +1137,18 @@ import type { IntBlockProposerCanonicalServiceListData, IntBlockProposerCanonicalServiceListError, IntBlockProposerCanonicalServiceListResponse, + IntContractCreationServiceGetData, + IntContractCreationServiceGetError, + IntContractCreationServiceGetResponse, + IntContractCreationServiceListData, + IntContractCreationServiceListError, + IntContractCreationServiceListResponse, + IntContractSelfdestructServiceGetData, + IntContractSelfdestructServiceGetError, + IntContractSelfdestructServiceGetResponse, + IntContractSelfdestructServiceListData, + IntContractSelfdestructServiceListError, + IntContractSelfdestructServiceListResponse, IntContractStorageExpiry12mServiceGetData, IntContractStorageExpiry12mServiceGetError, IntContractStorageExpiry12mServiceGetResponse, @@ -1243,12 +1269,12 @@ import type { IntEngineGetBlobsServiceListData, IntEngineGetBlobsServiceListError, IntEngineGetBlobsServiceListResponse, - IntEngineNewPayloadFastestServiceGetData, - IntEngineNewPayloadFastestServiceGetError, - IntEngineNewPayloadFastestServiceGetResponse, - IntEngineNewPayloadFastestServiceListData, - IntEngineNewPayloadFastestServiceListError, - IntEngineNewPayloadFastestServiceListResponse, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetData, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetError, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponse, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListData, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListError, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponse, IntEngineNewPayloadServiceGetData, IntEngineNewPayloadServiceGetError, IntEngineNewPayloadServiceGetResponse, @@ -1261,6 +1287,12 @@ import type { IntExecutionBlockByDateServiceListData, IntExecutionBlockByDateServiceListError, IntExecutionBlockByDateServiceListResponse, + IntStorageSelfdestructDiffsServiceGetData, + IntStorageSelfdestructDiffsServiceGetError, + IntStorageSelfdestructDiffsServiceGetResponse, + IntStorageSelfdestructDiffsServiceListData, + IntStorageSelfdestructDiffsServiceListError, + IntStorageSelfdestructDiffsServiceListResponse, IntStorageSlotDiffByAddressSlotServiceGetData, IntStorageSlotDiffByAddressSlotServiceGetError, IntStorageSlotDiffByAddressSlotServiceGetResponse, @@ -6651,6 +6683,60 @@ export const fctNodeActiveLast24hServiceGetOptions = (options: Options) => + createQueryKey('fctNodeCpuUtilizationServiceList', options); + +/** + * List records + * + * Retrieve paginated results with optional filtering + */ +export const fctNodeCpuUtilizationServiceListOptions = (options?: Options) => + queryOptions< + FctNodeCpuUtilizationServiceListResponse, + FctNodeCpuUtilizationServiceListError, + FctNodeCpuUtilizationServiceListResponse, + ReturnType + >({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await fctNodeCpuUtilizationServiceList({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: fctNodeCpuUtilizationServiceListQueryKey(options), + }); + +export const fctNodeCpuUtilizationServiceGetQueryKey = (options: Options) => + createQueryKey('fctNodeCpuUtilizationServiceGet', options); + +/** + * Get record + * + * Retrieve a single record by wallclock_slot_start_date_time + */ +export const fctNodeCpuUtilizationServiceGetOptions = (options: Options) => + queryOptions< + FctNodeCpuUtilizationServiceGetResponse, + FctNodeCpuUtilizationServiceGetError, + FctNodeCpuUtilizationServiceGetResponse, + ReturnType + >({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await fctNodeCpuUtilizationServiceGet({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: fctNodeCpuUtilizationServiceGetQueryKey(options), + }); + export const fctOpcodeGasByOpcodeDailyServiceListQueryKey = ( options?: Options ) => createQueryKey('fctOpcodeGasByOpcodeDailyServiceList', options); @@ -8832,6 +8918,114 @@ export const intBlockProposerCanonicalServiceGetOptions = (options: Options) => + createQueryKey('intContractCreationServiceList', options); + +/** + * List records + * + * Retrieve paginated results with optional filtering + */ +export const intContractCreationServiceListOptions = (options?: Options) => + queryOptions< + IntContractCreationServiceListResponse, + IntContractCreationServiceListError, + IntContractCreationServiceListResponse, + ReturnType + >({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await intContractCreationServiceList({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: intContractCreationServiceListQueryKey(options), + }); + +export const intContractCreationServiceGetQueryKey = (options: Options) => + createQueryKey('intContractCreationServiceGet', options); + +/** + * Get record + * + * Retrieve a single record by block_number + */ +export const intContractCreationServiceGetOptions = (options: Options) => + queryOptions< + IntContractCreationServiceGetResponse, + IntContractCreationServiceGetError, + IntContractCreationServiceGetResponse, + ReturnType + >({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await intContractCreationServiceGet({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: intContractCreationServiceGetQueryKey(options), + }); + +export const intContractSelfdestructServiceListQueryKey = (options?: Options) => + createQueryKey('intContractSelfdestructServiceList', options); + +/** + * List records + * + * Retrieve paginated results with optional filtering + */ +export const intContractSelfdestructServiceListOptions = (options?: Options) => + queryOptions< + IntContractSelfdestructServiceListResponse, + IntContractSelfdestructServiceListError, + IntContractSelfdestructServiceListResponse, + ReturnType + >({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await intContractSelfdestructServiceList({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: intContractSelfdestructServiceListQueryKey(options), + }); + +export const intContractSelfdestructServiceGetQueryKey = (options: Options) => + createQueryKey('intContractSelfdestructServiceGet', options); + +/** + * Get record + * + * Retrieve a single record by block_number + */ +export const intContractSelfdestructServiceGetOptions = (options: Options) => + queryOptions< + IntContractSelfdestructServiceGetResponse, + IntContractSelfdestructServiceGetError, + IntContractSelfdestructServiceGetResponse, + ReturnType + >({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await intContractSelfdestructServiceGet({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: intContractSelfdestructServiceGetQueryKey(options), + }); + export const intContractStorageExpiry1mServiceListQueryKey = ( options?: Options ) => createQueryKey('intContractStorageExpiry1mServiceList', options); @@ -10068,26 +10262,26 @@ export const intEngineNewPayloadServiceGetOptions = (options: Options -) => createQueryKey('intEngineNewPayloadFastestServiceList', options); +export const intEngineNewPayloadFastestExecutionByNodeClassServiceListQueryKey = ( + options?: Options +) => createQueryKey('intEngineNewPayloadFastestExecutionByNodeClassServiceList', options); /** * List records * * Retrieve paginated results with optional filtering */ -export const intEngineNewPayloadFastestServiceListOptions = ( - options?: Options +export const intEngineNewPayloadFastestExecutionByNodeClassServiceListOptions = ( + options?: Options ) => queryOptions< - IntEngineNewPayloadFastestServiceListResponse, - IntEngineNewPayloadFastestServiceListError, - IntEngineNewPayloadFastestServiceListResponse, - ReturnType + IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponse, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListError, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponse, + ReturnType >({ queryFn: async ({ queryKey, signal }) => { - const { data } = await intEngineNewPayloadFastestServiceList({ + const { data } = await intEngineNewPayloadFastestExecutionByNodeClassServiceList({ ...options, ...queryKey[0], signal, @@ -10095,29 +10289,29 @@ export const intEngineNewPayloadFastestServiceListOptions = ( }); return data; }, - queryKey: intEngineNewPayloadFastestServiceListQueryKey(options), + queryKey: intEngineNewPayloadFastestExecutionByNodeClassServiceListQueryKey(options), }); -export const intEngineNewPayloadFastestServiceGetQueryKey = ( - options: Options -) => createQueryKey('intEngineNewPayloadFastestServiceGet', options); +export const intEngineNewPayloadFastestExecutionByNodeClassServiceGetQueryKey = ( + options: Options +) => createQueryKey('intEngineNewPayloadFastestExecutionByNodeClassServiceGet', options); /** * Get record * * Retrieve a single record by slot_start_date_time */ -export const intEngineNewPayloadFastestServiceGetOptions = ( - options: Options +export const intEngineNewPayloadFastestExecutionByNodeClassServiceGetOptions = ( + options: Options ) => queryOptions< - IntEngineNewPayloadFastestServiceGetResponse, - IntEngineNewPayloadFastestServiceGetError, - IntEngineNewPayloadFastestServiceGetResponse, - ReturnType + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponse, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetError, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponse, + ReturnType >({ queryFn: async ({ queryKey, signal }) => { - const { data } = await intEngineNewPayloadFastestServiceGet({ + const { data } = await intEngineNewPayloadFastestExecutionByNodeClassServiceGet({ ...options, ...queryKey[0], signal, @@ -10125,7 +10319,7 @@ export const intEngineNewPayloadFastestServiceGetOptions = ( }); return data; }, - queryKey: intEngineNewPayloadFastestServiceGetQueryKey(options), + queryKey: intEngineNewPayloadFastestExecutionByNodeClassServiceGetQueryKey(options), }); export const intExecutionBlockByDateServiceListQueryKey = (options?: Options) => @@ -10182,6 +10376,66 @@ export const intExecutionBlockByDateServiceGetOptions = (options: Options +) => createQueryKey('intStorageSelfdestructDiffsServiceList', options); + +/** + * List records + * + * Retrieve paginated results with optional filtering + */ +export const intStorageSelfdestructDiffsServiceListOptions = ( + options?: Options +) => + queryOptions< + IntStorageSelfdestructDiffsServiceListResponse, + IntStorageSelfdestructDiffsServiceListError, + IntStorageSelfdestructDiffsServiceListResponse, + ReturnType + >({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await intStorageSelfdestructDiffsServiceList({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: intStorageSelfdestructDiffsServiceListQueryKey(options), + }); + +export const intStorageSelfdestructDiffsServiceGetQueryKey = ( + options: Options +) => createQueryKey('intStorageSelfdestructDiffsServiceGet', options); + +/** + * Get record + * + * Retrieve a single record by block_number + */ +export const intStorageSelfdestructDiffsServiceGetOptions = ( + options: Options +) => + queryOptions< + IntStorageSelfdestructDiffsServiceGetResponse, + IntStorageSelfdestructDiffsServiceGetError, + IntStorageSelfdestructDiffsServiceGetResponse, + ReturnType + >({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await intStorageSelfdestructDiffsServiceGet({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }); + return data; + }, + queryKey: intStorageSelfdestructDiffsServiceGetQueryKey(options), + }); + export const intStorageSlotDiffServiceListQueryKey = (options?: Options) => createQueryKey('intStorageSlotDiffServiceList', options); diff --git a/src/api/client/client.gen.ts b/src/api/client/client.gen.ts index c445e3e5a..1eaee37dd 100644 --- a/src/api/client/client.gen.ts +++ b/src/api/client/client.gen.ts @@ -162,10 +162,16 @@ export const createClient = (config: Config = {}): Client => { case 'arrayBuffer': case 'blob': case 'formData': - case 'json': case 'text': data = await response[parseAs](); break; + case 'json': { + // Some servers return 200 with no Content-Length and empty body. + // response.json() would throw; read as text and parse if non-empty. + const text = await response.text(); + data = text ? JSON.parse(text) : {}; + break; + } case 'stream': return opts.responseStyle === 'data' ? response.body diff --git a/src/api/index.ts b/src/api/index.ts index 810997ab1..37ec5f40a 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -181,6 +181,8 @@ export { fctMissedSlotRateHourlyServiceList, fctNodeActiveLast24hServiceGet, fctNodeActiveLast24hServiceList, + fctNodeCpuUtilizationServiceGet, + fctNodeCpuUtilizationServiceList, fctOpcodeGasByOpcodeDailyServiceGet, fctOpcodeGasByOpcodeDailyServiceList, fctOpcodeGasByOpcodeHourlyServiceGet, @@ -257,6 +259,10 @@ export { intBlockOpcodeGasServiceList, intBlockProposerCanonicalServiceGet, intBlockProposerCanonicalServiceList, + intContractCreationServiceGet, + intContractCreationServiceList, + intContractSelfdestructServiceGet, + intContractSelfdestructServiceList, intContractStorageExpiry12mServiceGet, intContractStorageExpiry12mServiceList, intContractStorageExpiry18mServiceGet, @@ -297,12 +303,14 @@ export { intCustodyProbeServiceList, intEngineGetBlobsServiceGet, intEngineGetBlobsServiceList, - intEngineNewPayloadFastestServiceGet, - intEngineNewPayloadFastestServiceList, + intEngineNewPayloadFastestExecutionByNodeClassServiceGet, + intEngineNewPayloadFastestExecutionByNodeClassServiceList, intEngineNewPayloadServiceGet, intEngineNewPayloadServiceList, intExecutionBlockByDateServiceGet, intExecutionBlockByDateServiceList, + intStorageSelfdestructDiffsServiceGet, + intStorageSelfdestructDiffsServiceList, intStorageSlotDiffByAddressSlotServiceGet, intStorageSlotDiffByAddressSlotServiceList, intStorageSlotDiffServiceGet, @@ -1343,6 +1351,17 @@ export type { FctNodeActiveLast24hServiceListErrors, FctNodeActiveLast24hServiceListResponse, FctNodeActiveLast24hServiceListResponses, + FctNodeCpuUtilization, + FctNodeCpuUtilizationServiceGetData, + FctNodeCpuUtilizationServiceGetError, + FctNodeCpuUtilizationServiceGetErrors, + FctNodeCpuUtilizationServiceGetResponse, + FctNodeCpuUtilizationServiceGetResponses, + FctNodeCpuUtilizationServiceListData, + FctNodeCpuUtilizationServiceListError, + FctNodeCpuUtilizationServiceListErrors, + FctNodeCpuUtilizationServiceListResponse, + FctNodeCpuUtilizationServiceListResponses, FctOpcodeGasByOpcodeDaily, FctOpcodeGasByOpcodeDailyServiceGetData, FctOpcodeGasByOpcodeDailyServiceGetError, @@ -1708,6 +1727,7 @@ export type { GetFctMissedSlotRateDailyResponse, GetFctMissedSlotRateHourlyResponse, GetFctNodeActiveLast24hResponse, + GetFctNodeCpuUtilizationResponse, GetFctOpcodeGasByOpcodeDailyResponse, GetFctOpcodeGasByOpcodeHourlyResponse, GetFctOpcodeOpsDailyResponse, @@ -1746,6 +1766,8 @@ export type { GetIntBlockMevCanonicalResponse, GetIntBlockOpcodeGasResponse, GetIntBlockProposerCanonicalResponse, + GetIntContractCreationResponse, + GetIntContractSelfdestructResponse, GetIntContractStorageExpiry12mResponse, GetIntContractStorageExpiry18mResponse, GetIntContractStorageExpiry1mResponse, @@ -1766,9 +1788,10 @@ export type { GetIntCustodyProbeOrderBySlotResponse, GetIntCustodyProbeResponse, GetIntEngineGetBlobsResponse, - GetIntEngineNewPayloadFastestResponse, + GetIntEngineNewPayloadFastestExecutionByNodeClassResponse, GetIntEngineNewPayloadResponse, GetIntExecutionBlockByDateResponse, + GetIntStorageSelfdestructDiffsResponse, GetIntStorageSlotDiffByAddressSlotResponse, GetIntStorageSlotDiffResponse, GetIntStorageSlotExpiry12mResponse, @@ -1936,6 +1959,28 @@ export type { IntBlockProposerCanonicalServiceListErrors, IntBlockProposerCanonicalServiceListResponse, IntBlockProposerCanonicalServiceListResponses, + IntContractCreation, + IntContractCreationServiceGetData, + IntContractCreationServiceGetError, + IntContractCreationServiceGetErrors, + IntContractCreationServiceGetResponse, + IntContractCreationServiceGetResponses, + IntContractCreationServiceListData, + IntContractCreationServiceListError, + IntContractCreationServiceListErrors, + IntContractCreationServiceListResponse, + IntContractCreationServiceListResponses, + IntContractSelfdestruct, + IntContractSelfdestructServiceGetData, + IntContractSelfdestructServiceGetError, + IntContractSelfdestructServiceGetErrors, + IntContractSelfdestructServiceGetResponse, + IntContractSelfdestructServiceGetResponses, + IntContractSelfdestructServiceListData, + IntContractSelfdestructServiceListError, + IntContractSelfdestructServiceListErrors, + IntContractSelfdestructServiceListResponse, + IntContractSelfdestructServiceListResponses, IntContractStorageExpiry12m, IntContractStorageExpiry12mServiceGetData, IntContractStorageExpiry12mServiceGetError, @@ -2157,17 +2202,17 @@ export type { IntEngineGetBlobsServiceListResponse, IntEngineGetBlobsServiceListResponses, IntEngineNewPayload, - IntEngineNewPayloadFastest, - IntEngineNewPayloadFastestServiceGetData, - IntEngineNewPayloadFastestServiceGetError, - IntEngineNewPayloadFastestServiceGetErrors, - IntEngineNewPayloadFastestServiceGetResponse, - IntEngineNewPayloadFastestServiceGetResponses, - IntEngineNewPayloadFastestServiceListData, - IntEngineNewPayloadFastestServiceListError, - IntEngineNewPayloadFastestServiceListErrors, - IntEngineNewPayloadFastestServiceListResponse, - IntEngineNewPayloadFastestServiceListResponses, + IntEngineNewPayloadFastestExecutionByNodeClass, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetData, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetError, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetErrors, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponse, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponses, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListData, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListError, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListErrors, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponse, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponses, IntEngineNewPayloadServiceGetData, IntEngineNewPayloadServiceGetError, IntEngineNewPayloadServiceGetErrors, @@ -2189,6 +2234,17 @@ export type { IntExecutionBlockByDateServiceListErrors, IntExecutionBlockByDateServiceListResponse, IntExecutionBlockByDateServiceListResponses, + IntStorageSelfdestructDiffs, + IntStorageSelfdestructDiffsServiceGetData, + IntStorageSelfdestructDiffsServiceGetError, + IntStorageSelfdestructDiffsServiceGetErrors, + IntStorageSelfdestructDiffsServiceGetResponse, + IntStorageSelfdestructDiffsServiceGetResponses, + IntStorageSelfdestructDiffsServiceListData, + IntStorageSelfdestructDiffsServiceListError, + IntStorageSelfdestructDiffsServiceListErrors, + IntStorageSelfdestructDiffsServiceListResponse, + IntStorageSelfdestructDiffsServiceListResponses, IntStorageSlotDiff, IntStorageSlotDiffByAddressSlot, IntStorageSlotDiffByAddressSlotServiceGetData, @@ -2532,6 +2588,7 @@ export type { ListFctMissedSlotRateDailyResponse, ListFctMissedSlotRateHourlyResponse, ListFctNodeActiveLast24hResponse, + ListFctNodeCpuUtilizationResponse, ListFctOpcodeGasByOpcodeDailyResponse, ListFctOpcodeGasByOpcodeHourlyResponse, ListFctOpcodeOpsDailyResponse, @@ -2570,6 +2627,8 @@ export type { ListIntBlockMevCanonicalResponse, ListIntBlockOpcodeGasResponse, ListIntBlockProposerCanonicalResponse, + ListIntContractCreationResponse, + ListIntContractSelfdestructResponse, ListIntContractStorageExpiry12mResponse, ListIntContractStorageExpiry18mResponse, ListIntContractStorageExpiry1mResponse, @@ -2590,9 +2649,10 @@ export type { ListIntCustodyProbeOrderBySlotResponse, ListIntCustodyProbeResponse, ListIntEngineGetBlobsResponse, - ListIntEngineNewPayloadFastestResponse, + ListIntEngineNewPayloadFastestExecutionByNodeClassResponse, ListIntEngineNewPayloadResponse, ListIntExecutionBlockByDateResponse, + ListIntStorageSelfdestructDiffsResponse, ListIntStorageSlotDiffByAddressSlotResponse, ListIntStorageSlotDiffResponse, ListIntStorageSlotExpiry12mResponse, diff --git a/src/api/sdk.gen.ts b/src/api/sdk.gen.ts index 42d4e69c8..fda9063a1 100644 --- a/src/api/sdk.gen.ts +++ b/src/api/sdk.gen.ts @@ -543,6 +543,12 @@ import type { FctNodeActiveLast24hServiceListData, FctNodeActiveLast24hServiceListErrors, FctNodeActiveLast24hServiceListResponses, + FctNodeCpuUtilizationServiceGetData, + FctNodeCpuUtilizationServiceGetErrors, + FctNodeCpuUtilizationServiceGetResponses, + FctNodeCpuUtilizationServiceListData, + FctNodeCpuUtilizationServiceListErrors, + FctNodeCpuUtilizationServiceListResponses, FctOpcodeGasByOpcodeDailyServiceGetData, FctOpcodeGasByOpcodeDailyServiceGetErrors, FctOpcodeGasByOpcodeDailyServiceGetResponses, @@ -771,6 +777,18 @@ import type { IntBlockProposerCanonicalServiceListData, IntBlockProposerCanonicalServiceListErrors, IntBlockProposerCanonicalServiceListResponses, + IntContractCreationServiceGetData, + IntContractCreationServiceGetErrors, + IntContractCreationServiceGetResponses, + IntContractCreationServiceListData, + IntContractCreationServiceListErrors, + IntContractCreationServiceListResponses, + IntContractSelfdestructServiceGetData, + IntContractSelfdestructServiceGetErrors, + IntContractSelfdestructServiceGetResponses, + IntContractSelfdestructServiceListData, + IntContractSelfdestructServiceListErrors, + IntContractSelfdestructServiceListResponses, IntContractStorageExpiry12mServiceGetData, IntContractStorageExpiry12mServiceGetErrors, IntContractStorageExpiry12mServiceGetResponses, @@ -891,12 +909,12 @@ import type { IntEngineGetBlobsServiceListData, IntEngineGetBlobsServiceListErrors, IntEngineGetBlobsServiceListResponses, - IntEngineNewPayloadFastestServiceGetData, - IntEngineNewPayloadFastestServiceGetErrors, - IntEngineNewPayloadFastestServiceGetResponses, - IntEngineNewPayloadFastestServiceListData, - IntEngineNewPayloadFastestServiceListErrors, - IntEngineNewPayloadFastestServiceListResponses, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetData, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetErrors, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponses, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListData, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListErrors, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponses, IntEngineNewPayloadServiceGetData, IntEngineNewPayloadServiceGetErrors, IntEngineNewPayloadServiceGetResponses, @@ -909,6 +927,12 @@ import type { IntExecutionBlockByDateServiceListData, IntExecutionBlockByDateServiceListErrors, IntExecutionBlockByDateServiceListResponses, + IntStorageSelfdestructDiffsServiceGetData, + IntStorageSelfdestructDiffsServiceGetErrors, + IntStorageSelfdestructDiffsServiceGetResponses, + IntStorageSelfdestructDiffsServiceListData, + IntStorageSelfdestructDiffsServiceListErrors, + IntStorageSelfdestructDiffsServiceListResponses, IntStorageSlotDiffByAddressSlotServiceGetData, IntStorageSlotDiffByAddressSlotServiceGetErrors, IntStorageSlotDiffByAddressSlotServiceGetResponses, @@ -1409,6 +1433,10 @@ import { zFctNodeActiveLast24hServiceGetResponse, zFctNodeActiveLast24hServiceListData, zFctNodeActiveLast24hServiceListResponse, + zFctNodeCpuUtilizationServiceGetData, + zFctNodeCpuUtilizationServiceGetResponse, + zFctNodeCpuUtilizationServiceListData, + zFctNodeCpuUtilizationServiceListResponse, zFctOpcodeGasByOpcodeDailyServiceGetData, zFctOpcodeGasByOpcodeDailyServiceGetResponse, zFctOpcodeGasByOpcodeDailyServiceListData, @@ -1561,6 +1589,14 @@ import { zIntBlockProposerCanonicalServiceGetResponse, zIntBlockProposerCanonicalServiceListData, zIntBlockProposerCanonicalServiceListResponse, + zIntContractCreationServiceGetData, + zIntContractCreationServiceGetResponse, + zIntContractCreationServiceListData, + zIntContractCreationServiceListResponse, + zIntContractSelfdestructServiceGetData, + zIntContractSelfdestructServiceGetResponse, + zIntContractSelfdestructServiceListData, + zIntContractSelfdestructServiceListResponse, zIntContractStorageExpiry12mServiceGetData, zIntContractStorageExpiry12mServiceGetResponse, zIntContractStorageExpiry12mServiceListData, @@ -1641,10 +1677,10 @@ import { zIntEngineGetBlobsServiceGetResponse, zIntEngineGetBlobsServiceListData, zIntEngineGetBlobsServiceListResponse, - zIntEngineNewPayloadFastestServiceGetData, - zIntEngineNewPayloadFastestServiceGetResponse, - zIntEngineNewPayloadFastestServiceListData, - zIntEngineNewPayloadFastestServiceListResponse, + zIntEngineNewPayloadFastestExecutionByNodeClassServiceGetData, + zIntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponse, + zIntEngineNewPayloadFastestExecutionByNodeClassServiceListData, + zIntEngineNewPayloadFastestExecutionByNodeClassServiceListResponse, zIntEngineNewPayloadServiceGetData, zIntEngineNewPayloadServiceGetResponse, zIntEngineNewPayloadServiceListData, @@ -1653,6 +1689,10 @@ import { zIntExecutionBlockByDateServiceGetResponse, zIntExecutionBlockByDateServiceListData, zIntExecutionBlockByDateServiceListResponse, + zIntStorageSelfdestructDiffsServiceGetData, + zIntStorageSelfdestructDiffsServiceGetResponse, + zIntStorageSelfdestructDiffsServiceListData, + zIntStorageSelfdestructDiffsServiceListResponse, zIntStorageSlotDiffByAddressSlotServiceGetData, zIntStorageSlotDiffByAddressSlotServiceGetResponse, zIntStorageSlotDiffByAddressSlotServiceListData, @@ -5162,6 +5202,44 @@ export const fctNodeActiveLast24hServiceGet = ( + options?: Options +) => + (options?.client ?? client).get< + FctNodeCpuUtilizationServiceListResponses, + FctNodeCpuUtilizationServiceListErrors, + ThrowOnError + >({ + requestValidator: async data => await zFctNodeCpuUtilizationServiceListData.parseAsync(data), + responseValidator: async data => await zFctNodeCpuUtilizationServiceListResponse.parseAsync(data), + url: '/api/v1/fct_node_cpu_utilization', + ...options, + }); + +/** + * Get record + * + * Retrieve a single record by wallclock_slot_start_date_time + */ +export const fctNodeCpuUtilizationServiceGet = ( + options: Options +) => + (options.client ?? client).get< + FctNodeCpuUtilizationServiceGetResponses, + FctNodeCpuUtilizationServiceGetErrors, + ThrowOnError + >({ + requestValidator: async data => await zFctNodeCpuUtilizationServiceGetData.parseAsync(data), + responseValidator: async data => await zFctNodeCpuUtilizationServiceGetResponse.parseAsync(data), + url: '/api/v1/fct_node_cpu_utilization/{wallclock_slot_start_date_time}', + ...options, + }); + /** * List records * @@ -6596,6 +6674,82 @@ export const intBlockProposerCanonicalServiceGet = ( + options?: Options +) => + (options?.client ?? client).get< + IntContractCreationServiceListResponses, + IntContractCreationServiceListErrors, + ThrowOnError + >({ + requestValidator: async data => await zIntContractCreationServiceListData.parseAsync(data), + responseValidator: async data => await zIntContractCreationServiceListResponse.parseAsync(data), + url: '/api/v1/int_contract_creation', + ...options, + }); + +/** + * Get record + * + * Retrieve a single record by block_number + */ +export const intContractCreationServiceGet = ( + options: Options +) => + (options.client ?? client).get< + IntContractCreationServiceGetResponses, + IntContractCreationServiceGetErrors, + ThrowOnError + >({ + requestValidator: async data => await zIntContractCreationServiceGetData.parseAsync(data), + responseValidator: async data => await zIntContractCreationServiceGetResponse.parseAsync(data), + url: '/api/v1/int_contract_creation/{block_number}', + ...options, + }); + +/** + * List records + * + * Retrieve paginated results with optional filtering + */ +export const intContractSelfdestructServiceList = ( + options?: Options +) => + (options?.client ?? client).get< + IntContractSelfdestructServiceListResponses, + IntContractSelfdestructServiceListErrors, + ThrowOnError + >({ + requestValidator: async data => await zIntContractSelfdestructServiceListData.parseAsync(data), + responseValidator: async data => await zIntContractSelfdestructServiceListResponse.parseAsync(data), + url: '/api/v1/int_contract_selfdestruct', + ...options, + }); + +/** + * Get record + * + * Retrieve a single record by block_number + */ +export const intContractSelfdestructServiceGet = ( + options: Options +) => + (options.client ?? client).get< + IntContractSelfdestructServiceGetResponses, + IntContractSelfdestructServiceGetErrors, + ThrowOnError + >({ + requestValidator: async data => await zIntContractSelfdestructServiceGetData.parseAsync(data), + responseValidator: async data => await zIntContractSelfdestructServiceGetResponse.parseAsync(data), + url: '/api/v1/int_contract_selfdestruct/{block_number}', + ...options, + }); + /** * List records * @@ -7392,17 +7546,19 @@ export const intEngineNewPayloadServiceGet = ( - options?: Options +export const intEngineNewPayloadFastestExecutionByNodeClassServiceList = ( + options?: Options ) => (options?.client ?? client).get< - IntEngineNewPayloadFastestServiceListResponses, - IntEngineNewPayloadFastestServiceListErrors, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponses, + IntEngineNewPayloadFastestExecutionByNodeClassServiceListErrors, ThrowOnError >({ - requestValidator: async data => await zIntEngineNewPayloadFastestServiceListData.parseAsync(data), - responseValidator: async data => await zIntEngineNewPayloadFastestServiceListResponse.parseAsync(data), - url: '/api/v1/int_engine_new_payload_fastest', + requestValidator: async data => + await zIntEngineNewPayloadFastestExecutionByNodeClassServiceListData.parseAsync(data), + responseValidator: async data => + await zIntEngineNewPayloadFastestExecutionByNodeClassServiceListResponse.parseAsync(data), + url: '/api/v1/int_engine_new_payload_fastest_execution_by_node_class', ...options, }); @@ -7411,17 +7567,19 @@ export const intEngineNewPayloadFastestServiceList = ( - options: Options +export const intEngineNewPayloadFastestExecutionByNodeClassServiceGet = ( + options: Options ) => (options.client ?? client).get< - IntEngineNewPayloadFastestServiceGetResponses, - IntEngineNewPayloadFastestServiceGetErrors, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponses, + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetErrors, ThrowOnError >({ - requestValidator: async data => await zIntEngineNewPayloadFastestServiceGetData.parseAsync(data), - responseValidator: async data => await zIntEngineNewPayloadFastestServiceGetResponse.parseAsync(data), - url: '/api/v1/int_engine_new_payload_fastest/{slot_start_date_time}', + requestValidator: async data => + await zIntEngineNewPayloadFastestExecutionByNodeClassServiceGetData.parseAsync(data), + responseValidator: async data => + await zIntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponse.parseAsync(data), + url: '/api/v1/int_engine_new_payload_fastest_execution_by_node_class/{slot_start_date_time}', ...options, }); @@ -7463,6 +7621,44 @@ export const intExecutionBlockByDateServiceGet = ( + options?: Options +) => + (options?.client ?? client).get< + IntStorageSelfdestructDiffsServiceListResponses, + IntStorageSelfdestructDiffsServiceListErrors, + ThrowOnError + >({ + requestValidator: async data => await zIntStorageSelfdestructDiffsServiceListData.parseAsync(data), + responseValidator: async data => await zIntStorageSelfdestructDiffsServiceListResponse.parseAsync(data), + url: '/api/v1/int_storage_selfdestruct_diffs', + ...options, + }); + +/** + * Get record + * + * Retrieve a single record by block_number + */ +export const intStorageSelfdestructDiffsServiceGet = ( + options: Options +) => + (options.client ?? client).get< + IntStorageSelfdestructDiffsServiceGetResponses, + IntStorageSelfdestructDiffsServiceGetErrors, + ThrowOnError + >({ + requestValidator: async data => await zIntStorageSelfdestructDiffsServiceGetData.parseAsync(data), + responseValidator: async data => await zIntStorageSelfdestructDiffsServiceGetResponse.parseAsync(data), + url: '/api/v1/int_storage_selfdestruct_diffs/{block_number}', + ...options, + }); + /** * List records * diff --git a/src/api/types.gen.ts b/src/api/types.gen.ts index 6c96b1476..4c7cd6b42 100644 --- a/src/api/types.gen.ts +++ b/src/api/types.gen.ts @@ -4560,6 +4560,65 @@ export type FctNodeActiveLast24h = { username?: string; }; +export type FctNodeCpuUtilization = { + /** + * Client type: CL or EL + */ + client_type?: string; + /** + * Maximum CPU core utilization percentage (100pct = 1 core) + */ + max_core_pct?: number; + /** + * Maximum single core utilization percentage (0-100pct) + */ + max_single_core_pct?: number; + /** + * Mean CPU core utilization percentage (100pct = 1 core) + */ + mean_core_pct?: number; + /** + * Name of the observoor client that collected the data + */ + meta_client_name?: string; + /** + * Ethereum network name + */ + meta_network_name?: string; + /** + * Minimum CPU core utilization percentage (100pct = 1 core) + */ + min_core_pct?: number; + /** + * Node classification for filtering (e.g. eip7870) + */ + node_class?: string; + /** + * Process ID of the monitored client + */ + pid?: number; + /** + * Total system CPU cores + */ + system_cores?: number; + /** + * Timestamp when the record was last updated + */ + updated_date_time?: number; + /** + * The wallclock slot number + */ + wallclock_slot?: number; + /** + * The wall clock time when the slot started + */ + wallclock_slot_start_date_time?: number; + /** + * Start of the sub-slot aggregation window + */ + window_start?: number; +}; + export type FctOpcodeGasByOpcodeDaily = { /** * Average executions per block @@ -6149,6 +6208,13 @@ export type GetFctNodeActiveLast24hResponse = { item?: FctNodeActiveLast24h; }; +/** + * Response for getting a single fct_node_cpu_utilization record + */ +export type GetFctNodeCpuUtilizationResponse = { + item?: FctNodeCpuUtilization; +}; + /** * Response for getting a single fct_opcode_gas_by_opcode_daily record */ @@ -6415,6 +6481,20 @@ export type GetIntBlockProposerCanonicalResponse = { item?: IntBlockProposerCanonical; }; +/** + * Response for getting a single int_contract_creation record + */ +export type GetIntContractCreationResponse = { + item?: IntContractCreation; +}; + +/** + * Response for getting a single int_contract_selfdestruct record + */ +export type GetIntContractSelfdestructResponse = { + item?: IntContractSelfdestruct; +}; + /** * Response for getting a single int_contract_storage_expiry_1m record */ @@ -6556,10 +6636,10 @@ export type GetIntEngineGetBlobsResponse = { }; /** - * Response for getting a single int_engine_new_payload_fastest record + * Response for getting a single int_engine_new_payload_fastest_execution_by_node_class record */ -export type GetIntEngineNewPayloadFastestResponse = { - item?: IntEngineNewPayloadFastest; +export type GetIntEngineNewPayloadFastestExecutionByNodeClassResponse = { + item?: IntEngineNewPayloadFastestExecutionByNodeClass; }; /** @@ -6576,6 +6656,13 @@ export type GetIntExecutionBlockByDateResponse = { item?: IntExecutionBlockByDate; }; +/** + * Response for getting a single int_storage_selfdestruct_diffs record + */ +export type GetIntStorageSelfdestructDiffsResponse = { + item?: IntStorageSelfdestructDiffs; +}; + /** * Response for getting a single int_storage_slot_diff_by_address_slot record */ @@ -7355,6 +7442,96 @@ export type IntBlockProposerCanonical = { updated_date_time?: number; }; +export type IntContractCreation = { + /** + * Block where contract was created + */ + block_number?: number; + /** + * Address of created contract + */ + contract_address?: string; + /** + * Address that deployed the contract + */ + deployer?: string; + /** + * Factory contract address if applicable + */ + factory?: string; + /** + * Hash of the initialization code + */ + init_code_hash?: string; + /** + * Position within transaction + */ + internal_index?: number; + /** + * Transaction hash + */ + transaction_hash?: string; + /** + * Position in block + */ + transaction_index?: number; + /** + * Timestamp when the record was last updated + */ + updated_date_time?: number; +}; + +export type IntContractSelfdestruct = { + /** + * Contract that was destroyed + */ + address?: string; + /** + * Address receiving the ETH + */ + beneficiary?: string; + /** + * Block where SELFDESTRUCT occurred + */ + block_number?: number; + /** + * Block where contract was created (if known) + */ + creation_block?: number | null; + /** + * Transaction that created the contract (if known) + */ + creation_transaction_hash?: string | null; + /** + * True if contract was created and destroyed in the same transaction - storage always cleared per EIP-6780 + */ + ephemeral?: boolean; + /** + * Position within transaction traces + */ + internal_index?: number; + /** + * True if storage was cleared (pre-Shanghai OR ephemeral) + */ + storage_cleared?: boolean; + /** + * Transaction hash + */ + transaction_hash?: string; + /** + * Position in block + */ + transaction_index?: number; + /** + * Timestamp when the record was last updated + */ + updated_date_time?: number; + /** + * Amount of ETH sent to beneficiary + */ + value_transferred?: string; +}; + export type IntContractStorageExpiry1m = { /** * Count of slots in the contract at expiry time @@ -8426,7 +8603,7 @@ export type IntEngineNewPayload = { validation_error?: string | null; }; -export type IntEngineNewPayloadFastest = { +export type IntEngineNewPayloadFastestExecutionByNodeClass = { /** * Execution block hash (hex encoded with 0x prefix) */ @@ -8488,6 +8665,45 @@ export type IntExecutionBlockByDate = { updated_date_time?: number; }; +export type IntStorageSelfdestructDiffs = { + /** + * Contract address that was selfdestructed + */ + address?: string; + /** + * Block where SELFDESTRUCT occurred + */ + block_number?: number; + /** + * Value before clearing (last known value) + */ + from_value?: string; + /** + * Internal index of the SELFDESTRUCT trace + */ + internal_index?: number; + /** + * Storage slot key being cleared + */ + slot?: string; + /** + * Value after clearing (always 0x00...00) + */ + to_value?: string; + /** + * Transaction hash of the SELFDESTRUCT + */ + transaction_hash?: string; + /** + * Transaction index within the block + */ + transaction_index?: number; + /** + * Timestamp when the record was last updated + */ + updated_date_time?: number; +}; + export type IntStorageSlotDiff = { /** * The contract address @@ -10489,6 +10705,20 @@ export type ListFctNodeActiveLast24hResponse = { next_page_token?: string; }; +/** + * Response for listing fct_node_cpu_utilization records + */ +export type ListFctNodeCpuUtilizationResponse = { + /** + * The list of fct_node_cpu_utilization. + */ + fct_node_cpu_utilization?: Array; + /** + * A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. + */ + next_page_token?: string; +}; + /** * Response for listing fct_opcode_gas_by_opcode_daily records */ @@ -11021,6 +11251,34 @@ export type ListIntBlockProposerCanonicalResponse = { next_page_token?: string; }; +/** + * Response for listing int_contract_creation records + */ +export type ListIntContractCreationResponse = { + /** + * The list of int_contract_creation. + */ + int_contract_creation?: Array; + /** + * A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. + */ + next_page_token?: string; +}; + +/** + * Response for listing int_contract_selfdestruct records + */ +export type ListIntContractSelfdestructResponse = { + /** + * The list of int_contract_selfdestruct. + */ + int_contract_selfdestruct?: Array; + /** + * A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. + */ + next_page_token?: string; +}; + /** * Response for listing int_contract_storage_expiry_1m records */ @@ -11302,13 +11560,13 @@ export type ListIntEngineGetBlobsResponse = { }; /** - * Response for listing int_engine_new_payload_fastest records + * Response for listing int_engine_new_payload_fastest_execution_by_node_class records */ -export type ListIntEngineNewPayloadFastestResponse = { +export type ListIntEngineNewPayloadFastestExecutionByNodeClassResponse = { /** - * The list of int_engine_new_payload_fastest. + * The list of int_engine_new_payload_fastest_execution_by_node_class. */ - int_engine_new_payload_fastest?: Array; + int_engine_new_payload_fastest_execution_by_node_class?: Array; /** * A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. */ @@ -11343,6 +11601,20 @@ export type ListIntExecutionBlockByDateResponse = { next_page_token?: string; }; +/** + * Response for listing int_storage_selfdestruct_diffs records + */ +export type ListIntStorageSelfdestructDiffsResponse = { + /** + * The list of int_storage_selfdestruct_diffs. + */ + int_storage_selfdestruct_diffs?: Array; + /** + * A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. + */ + next_page_token?: string; +}; + /** * Response for listing int_storage_slot_diff_by_address_slot records */ @@ -54833,82 +55105,554 @@ export type FctNodeActiveLast24hServiceGetResponses = { export type FctNodeActiveLast24hServiceGetResponse = FctNodeActiveLast24hServiceGetResponses[keyof FctNodeActiveLast24hServiceGetResponses]; -export type FctOpcodeGasByOpcodeDailyServiceListData = { +export type FctNodeCpuUtilizationServiceListData = { body?: never; path?: never; query?: { /** - * Start of the day period (filter: eq) + * The wall clock time when the slot started (filter: eq) */ - day_start_date_eq?: string; + wallclock_slot_start_date_time_eq?: number; /** - * Start of the day period (filter: ne) + * The wall clock time when the slot started (filter: ne) */ - day_start_date_ne?: string; + wallclock_slot_start_date_time_ne?: number; /** - * Start of the day period (filter: contains) + * The wall clock time when the slot started (filter: lt) */ - day_start_date_contains?: string; + wallclock_slot_start_date_time_lt?: number; /** - * Start of the day period (filter: starts_with) + * The wall clock time when the slot started (filter: lte) */ - day_start_date_starts_with?: string; + wallclock_slot_start_date_time_lte?: number; /** - * Start of the day period (filter: ends_with) + * The wall clock time when the slot started (filter: gt) */ - day_start_date_ends_with?: string; + wallclock_slot_start_date_time_gt?: number; /** - * Start of the day period (filter: like) + * The wall clock time when the slot started (filter: gte) */ - day_start_date_like?: string; + wallclock_slot_start_date_time_gte?: number; /** - * Start of the day period (filter: not_like) + * The wall clock time when the slot started (filter: between_min) */ - day_start_date_not_like?: string; + wallclock_slot_start_date_time_between_min?: number; /** - * Start of the day period (filter: in_values) (comma-separated list) + * The wall clock time when the slot started (filter: between_max_value) */ - day_start_date_in_values?: string; + wallclock_slot_start_date_time_between_max_value?: number; /** - * Start of the day period (filter: not_in_values) (comma-separated list) + * The wall clock time when the slot started (filter: in_values) (comma-separated list) */ - day_start_date_not_in_values?: string; + wallclock_slot_start_date_time_in_values?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: eq) + * The wall clock time when the slot started (filter: not_in_values) (comma-separated list) */ - opcode_eq?: string; + wallclock_slot_start_date_time_not_in_values?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: ne) + * Name of the observoor client that collected the data (filter: eq) */ - opcode_ne?: string; + meta_client_name_eq?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: contains) + * Name of the observoor client that collected the data (filter: ne) */ - opcode_contains?: string; + meta_client_name_ne?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: starts_with) + * Name of the observoor client that collected the data (filter: contains) */ - opcode_starts_with?: string; + meta_client_name_contains?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: ends_with) + * Name of the observoor client that collected the data (filter: starts_with) */ - opcode_ends_with?: string; + meta_client_name_starts_with?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: like) + * Name of the observoor client that collected the data (filter: ends_with) */ - opcode_like?: string; + meta_client_name_ends_with?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: not_like) + * Name of the observoor client that collected the data (filter: like) */ - opcode_not_like?: string; + meta_client_name_like?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: in_values) (comma-separated list) + * Name of the observoor client that collected the data (filter: not_like) */ - opcode_in_values?: string; + meta_client_name_not_like?: string; /** - * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: not_in_values) (comma-separated list) + * Name of the observoor client that collected the data (filter: in_values) (comma-separated list) */ - opcode_not_in_values?: string; + meta_client_name_in_values?: string; + /** + * Name of the observoor client that collected the data (filter: not_in_values) (comma-separated list) + */ + meta_client_name_not_in_values?: string; + /** + * Client type: CL or EL (filter: eq) + */ + client_type_eq?: string; + /** + * Client type: CL or EL (filter: ne) + */ + client_type_ne?: string; + /** + * Client type: CL or EL (filter: contains) + */ + client_type_contains?: string; + /** + * Client type: CL or EL (filter: starts_with) + */ + client_type_starts_with?: string; + /** + * Client type: CL or EL (filter: ends_with) + */ + client_type_ends_with?: string; + /** + * Client type: CL or EL (filter: like) + */ + client_type_like?: string; + /** + * Client type: CL or EL (filter: not_like) + */ + client_type_not_like?: string; + /** + * Client type: CL or EL (filter: in_values) (comma-separated list) + */ + client_type_in_values?: string; + /** + * Client type: CL or EL (filter: not_in_values) (comma-separated list) + */ + client_type_not_in_values?: string; + /** + * Process ID of the monitored client (filter: eq) + */ + pid_eq?: number; + /** + * Process ID of the monitored client (filter: ne) + */ + pid_ne?: number; + /** + * Process ID of the monitored client (filter: lt) + */ + pid_lt?: number; + /** + * Process ID of the monitored client (filter: lte) + */ + pid_lte?: number; + /** + * Process ID of the monitored client (filter: gt) + */ + pid_gt?: number; + /** + * Process ID of the monitored client (filter: gte) + */ + pid_gte?: number; + /** + * Process ID of the monitored client (filter: between_min) + */ + pid_between_min?: number; + /** + * Process ID of the monitored client (filter: between_max_value) + */ + pid_between_max_value?: number; + /** + * Process ID of the monitored client (filter: in_values) (comma-separated list) + */ + pid_in_values?: string; + /** + * Process ID of the monitored client (filter: not_in_values) (comma-separated list) + */ + pid_not_in_values?: string; + /** + * Start of the sub-slot aggregation window (filter: eq) + */ + window_start_eq?: number; + /** + * Start of the sub-slot aggregation window (filter: ne) + */ + window_start_ne?: number; + /** + * Start of the sub-slot aggregation window (filter: lt) + */ + window_start_lt?: number; + /** + * Start of the sub-slot aggregation window (filter: lte) + */ + window_start_lte?: number; + /** + * Start of the sub-slot aggregation window (filter: gt) + */ + window_start_gt?: number; + /** + * Start of the sub-slot aggregation window (filter: gte) + */ + window_start_gte?: number; + /** + * Start of the sub-slot aggregation window (filter: between_min) + */ + window_start_between_min?: number; + /** + * Start of the sub-slot aggregation window (filter: between_max_value) + */ + window_start_between_max_value?: number; + /** + * Start of the sub-slot aggregation window (filter: in_values) (comma-separated list) + */ + window_start_in_values?: string; + /** + * Start of the sub-slot aggregation window (filter: not_in_values) (comma-separated list) + */ + window_start_not_in_values?: string; + /** + * Timestamp when the record was last updated (filter: eq) + */ + updated_date_time_eq?: number; + /** + * Timestamp when the record was last updated (filter: ne) + */ + updated_date_time_ne?: number; + /** + * Timestamp when the record was last updated (filter: lt) + */ + updated_date_time_lt?: number; + /** + * Timestamp when the record was last updated (filter: lte) + */ + updated_date_time_lte?: number; + /** + * Timestamp when the record was last updated (filter: gt) + */ + updated_date_time_gt?: number; + /** + * Timestamp when the record was last updated (filter: gte) + */ + updated_date_time_gte?: number; + /** + * Timestamp when the record was last updated (filter: between_min) + */ + updated_date_time_between_min?: number; + /** + * Timestamp when the record was last updated (filter: between_max_value) + */ + updated_date_time_between_max_value?: number; + /** + * Timestamp when the record was last updated (filter: in_values) (comma-separated list) + */ + updated_date_time_in_values?: string; + /** + * Timestamp when the record was last updated (filter: not_in_values) (comma-separated list) + */ + updated_date_time_not_in_values?: string; + /** + * The wallclock slot number (filter: eq) + */ + wallclock_slot_eq?: number; + /** + * The wallclock slot number (filter: ne) + */ + wallclock_slot_ne?: number; + /** + * The wallclock slot number (filter: lt) + */ + wallclock_slot_lt?: number; + /** + * The wallclock slot number (filter: lte) + */ + wallclock_slot_lte?: number; + /** + * The wallclock slot number (filter: gt) + */ + wallclock_slot_gt?: number; + /** + * The wallclock slot number (filter: gte) + */ + wallclock_slot_gte?: number; + /** + * The wallclock slot number (filter: between_min) + */ + wallclock_slot_between_min?: number; + /** + * The wallclock slot number (filter: between_max_value) + */ + wallclock_slot_between_max_value?: number; + /** + * The wallclock slot number (filter: in_values) (comma-separated list) + */ + wallclock_slot_in_values?: string; + /** + * The wallclock slot number (filter: not_in_values) (comma-separated list) + */ + wallclock_slot_not_in_values?: string; + /** + * Ethereum network name (filter: eq) + */ + meta_network_name_eq?: string; + /** + * Ethereum network name (filter: ne) + */ + meta_network_name_ne?: string; + /** + * Ethereum network name (filter: contains) + */ + meta_network_name_contains?: string; + /** + * Ethereum network name (filter: starts_with) + */ + meta_network_name_starts_with?: string; + /** + * Ethereum network name (filter: ends_with) + */ + meta_network_name_ends_with?: string; + /** + * Ethereum network name (filter: like) + */ + meta_network_name_like?: string; + /** + * Ethereum network name (filter: not_like) + */ + meta_network_name_not_like?: string; + /** + * Ethereum network name (filter: in_values) (comma-separated list) + */ + meta_network_name_in_values?: string; + /** + * Ethereum network name (filter: not_in_values) (comma-separated list) + */ + meta_network_name_not_in_values?: string; + /** + * Total system CPU cores (filter: eq) + */ + system_cores_eq?: number; + /** + * Total system CPU cores (filter: ne) + */ + system_cores_ne?: number; + /** + * Total system CPU cores (filter: lt) + */ + system_cores_lt?: number; + /** + * Total system CPU cores (filter: lte) + */ + system_cores_lte?: number; + /** + * Total system CPU cores (filter: gt) + */ + system_cores_gt?: number; + /** + * Total system CPU cores (filter: gte) + */ + system_cores_gte?: number; + /** + * Total system CPU cores (filter: between_min) + */ + system_cores_between_min?: number; + /** + * Total system CPU cores (filter: between_max_value) + */ + system_cores_between_max_value?: number; + /** + * Total system CPU cores (filter: in_values) (comma-separated list) + */ + system_cores_in_values?: string; + /** + * Total system CPU cores (filter: not_in_values) (comma-separated list) + */ + system_cores_not_in_values?: string; + /** + * Filter mean_core_pct using value + */ + mean_core_pct_value?: number; + /** + * Filter min_core_pct using value + */ + min_core_pct_value?: number; + /** + * Filter max_core_pct using value + */ + max_core_pct_value?: number; + /** + * Filter max_single_core_pct using value + */ + max_single_core_pct_value?: number; + /** + * Node classification for filtering (e.g. eip7870) (filter: eq) + */ + node_class_eq?: string; + /** + * Node classification for filtering (e.g. eip7870) (filter: ne) + */ + node_class_ne?: string; + /** + * Node classification for filtering (e.g. eip7870) (filter: contains) + */ + node_class_contains?: string; + /** + * Node classification for filtering (e.g. eip7870) (filter: starts_with) + */ + node_class_starts_with?: string; + /** + * Node classification for filtering (e.g. eip7870) (filter: ends_with) + */ + node_class_ends_with?: string; + /** + * Node classification for filtering (e.g. eip7870) (filter: like) + */ + node_class_like?: string; + /** + * Node classification for filtering (e.g. eip7870) (filter: not_like) + */ + node_class_not_like?: string; + /** + * Node classification for filtering (e.g. eip7870) (filter: in_values) (comma-separated list) + */ + node_class_in_values?: string; + /** + * Node classification for filtering (e.g. eip7870) (filter: not_in_values) (comma-separated list) + */ + node_class_not_in_values?: string; + /** + * The maximum number of fct_node_cpu_utilization to return. If unspecified, at most 100 items will be returned. The maximum value is 10000; values above 10000 will be coerced to 10000. + */ + page_size?: number; + /** + * A page token, received from a previous `ListFctNodeCpuUtilization` call. Provide this to retrieve the subsequent page. + */ + page_token?: string; + /** + * The order of results. Format: comma-separated list of fields. Example: "foo,bar" or "foo desc,bar" for descending order on foo. If unspecified, results will be returned in the default order. + */ + order_by?: string; + }; + url: '/api/v1/fct_node_cpu_utilization'; +}; + +export type FctNodeCpuUtilizationServiceListErrors = { + /** + * Default error response + */ + default: Status; +}; + +export type FctNodeCpuUtilizationServiceListError = + FctNodeCpuUtilizationServiceListErrors[keyof FctNodeCpuUtilizationServiceListErrors]; + +export type FctNodeCpuUtilizationServiceListResponses = { + /** + * OK + */ + 200: ListFctNodeCpuUtilizationResponse; +}; + +export type FctNodeCpuUtilizationServiceListResponse = + FctNodeCpuUtilizationServiceListResponses[keyof FctNodeCpuUtilizationServiceListResponses]; + +export type FctNodeCpuUtilizationServiceGetData = { + body?: never; + path: { + /** + * The wall clock time when the slot started + */ + wallclock_slot_start_date_time: number; + }; + query?: never; + url: '/api/v1/fct_node_cpu_utilization/{wallclock_slot_start_date_time}'; +}; + +export type FctNodeCpuUtilizationServiceGetErrors = { + /** + * Default error response + */ + default: Status; +}; + +export type FctNodeCpuUtilizationServiceGetError = + FctNodeCpuUtilizationServiceGetErrors[keyof FctNodeCpuUtilizationServiceGetErrors]; + +export type FctNodeCpuUtilizationServiceGetResponses = { + /** + * OK + */ + 200: GetFctNodeCpuUtilizationResponse; +}; + +export type FctNodeCpuUtilizationServiceGetResponse = + FctNodeCpuUtilizationServiceGetResponses[keyof FctNodeCpuUtilizationServiceGetResponses]; + +export type FctOpcodeGasByOpcodeDailyServiceListData = { + body?: never; + path?: never; + query?: { + /** + * Start of the day period (filter: eq) + */ + day_start_date_eq?: string; + /** + * Start of the day period (filter: ne) + */ + day_start_date_ne?: string; + /** + * Start of the day period (filter: contains) + */ + day_start_date_contains?: string; + /** + * Start of the day period (filter: starts_with) + */ + day_start_date_starts_with?: string; + /** + * Start of the day period (filter: ends_with) + */ + day_start_date_ends_with?: string; + /** + * Start of the day period (filter: like) + */ + day_start_date_like?: string; + /** + * Start of the day period (filter: not_like) + */ + day_start_date_not_like?: string; + /** + * Start of the day period (filter: in_values) (comma-separated list) + */ + day_start_date_in_values?: string; + /** + * Start of the day period (filter: not_in_values) (comma-separated list) + */ + day_start_date_not_in_values?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: eq) + */ + opcode_eq?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: ne) + */ + opcode_ne?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: contains) + */ + opcode_contains?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: starts_with) + */ + opcode_starts_with?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: ends_with) + */ + opcode_ends_with?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: like) + */ + opcode_like?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: not_like) + */ + opcode_not_like?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: in_values) (comma-separated list) + */ + opcode_in_values?: string; + /** + * The EVM opcode name (e.g., SLOAD, ADD, CALL) (filter: not_in_values) (comma-separated list) + */ + opcode_not_in_values?: string; /** * Timestamp when the record was last updated (filter: eq) */ @@ -69723,6 +70467,886 @@ export type IntBlockProposerCanonicalServiceGetResponses = { export type IntBlockProposerCanonicalServiceGetResponse = IntBlockProposerCanonicalServiceGetResponses[keyof IntBlockProposerCanonicalServiceGetResponses]; +export type IntContractCreationServiceListData = { + body?: never; + path?: never; + query?: { + /** + * Block where contract was created (filter: eq) + */ + block_number_eq?: number; + /** + * Block where contract was created (filter: ne) + */ + block_number_ne?: number; + /** + * Block where contract was created (filter: lt) + */ + block_number_lt?: number; + /** + * Block where contract was created (filter: lte) + */ + block_number_lte?: number; + /** + * Block where contract was created (filter: gt) + */ + block_number_gt?: number; + /** + * Block where contract was created (filter: gte) + */ + block_number_gte?: number; + /** + * Block where contract was created (filter: between_min) + */ + block_number_between_min?: number; + /** + * Block where contract was created (filter: between_max_value) + */ + block_number_between_max_value?: number; + /** + * Block where contract was created (filter: in_values) (comma-separated list) + */ + block_number_in_values?: string; + /** + * Block where contract was created (filter: not_in_values) (comma-separated list) + */ + block_number_not_in_values?: string; + /** + * Address of created contract (filter: eq) + */ + contract_address_eq?: string; + /** + * Address of created contract (filter: ne) + */ + contract_address_ne?: string; + /** + * Address of created contract (filter: contains) + */ + contract_address_contains?: string; + /** + * Address of created contract (filter: starts_with) + */ + contract_address_starts_with?: string; + /** + * Address of created contract (filter: ends_with) + */ + contract_address_ends_with?: string; + /** + * Address of created contract (filter: like) + */ + contract_address_like?: string; + /** + * Address of created contract (filter: not_like) + */ + contract_address_not_like?: string; + /** + * Address of created contract (filter: in_values) (comma-separated list) + */ + contract_address_in_values?: string; + /** + * Address of created contract (filter: not_in_values) (comma-separated list) + */ + contract_address_not_in_values?: string; + /** + * Transaction hash (filter: eq) + */ + transaction_hash_eq?: string; + /** + * Transaction hash (filter: ne) + */ + transaction_hash_ne?: string; + /** + * Transaction hash (filter: contains) + */ + transaction_hash_contains?: string; + /** + * Transaction hash (filter: starts_with) + */ + transaction_hash_starts_with?: string; + /** + * Transaction hash (filter: ends_with) + */ + transaction_hash_ends_with?: string; + /** + * Transaction hash (filter: like) + */ + transaction_hash_like?: string; + /** + * Transaction hash (filter: not_like) + */ + transaction_hash_not_like?: string; + /** + * Transaction hash (filter: in_values) (comma-separated list) + */ + transaction_hash_in_values?: string; + /** + * Transaction hash (filter: not_in_values) (comma-separated list) + */ + transaction_hash_not_in_values?: string; + /** + * Timestamp when the record was last updated (filter: eq) + */ + updated_date_time_eq?: number; + /** + * Timestamp when the record was last updated (filter: ne) + */ + updated_date_time_ne?: number; + /** + * Timestamp when the record was last updated (filter: lt) + */ + updated_date_time_lt?: number; + /** + * Timestamp when the record was last updated (filter: lte) + */ + updated_date_time_lte?: number; + /** + * Timestamp when the record was last updated (filter: gt) + */ + updated_date_time_gt?: number; + /** + * Timestamp when the record was last updated (filter: gte) + */ + updated_date_time_gte?: number; + /** + * Timestamp when the record was last updated (filter: between_min) + */ + updated_date_time_between_min?: number; + /** + * Timestamp when the record was last updated (filter: between_max_value) + */ + updated_date_time_between_max_value?: number; + /** + * Timestamp when the record was last updated (filter: in_values) (comma-separated list) + */ + updated_date_time_in_values?: string; + /** + * Timestamp when the record was last updated (filter: not_in_values) (comma-separated list) + */ + updated_date_time_not_in_values?: string; + /** + * Position in block (filter: eq) + */ + transaction_index_eq?: number; + /** + * Position in block (filter: ne) + */ + transaction_index_ne?: number; + /** + * Position in block (filter: lt) + */ + transaction_index_lt?: number; + /** + * Position in block (filter: lte) + */ + transaction_index_lte?: number; + /** + * Position in block (filter: gt) + */ + transaction_index_gt?: number; + /** + * Position in block (filter: gte) + */ + transaction_index_gte?: number; + /** + * Position in block (filter: between_min) + */ + transaction_index_between_min?: number; + /** + * Position in block (filter: between_max_value) + */ + transaction_index_between_max_value?: number; + /** + * Position in block (filter: in_values) (comma-separated list) + */ + transaction_index_in_values?: string; + /** + * Position in block (filter: not_in_values) (comma-separated list) + */ + transaction_index_not_in_values?: string; + /** + * Position within transaction (filter: eq) + */ + internal_index_eq?: number; + /** + * Position within transaction (filter: ne) + */ + internal_index_ne?: number; + /** + * Position within transaction (filter: lt) + */ + internal_index_lt?: number; + /** + * Position within transaction (filter: lte) + */ + internal_index_lte?: number; + /** + * Position within transaction (filter: gt) + */ + internal_index_gt?: number; + /** + * Position within transaction (filter: gte) + */ + internal_index_gte?: number; + /** + * Position within transaction (filter: between_min) + */ + internal_index_between_min?: number; + /** + * Position within transaction (filter: between_max_value) + */ + internal_index_between_max_value?: number; + /** + * Position within transaction (filter: in_values) (comma-separated list) + */ + internal_index_in_values?: string; + /** + * Position within transaction (filter: not_in_values) (comma-separated list) + */ + internal_index_not_in_values?: string; + /** + * Address that deployed the contract (filter: eq) + */ + deployer_eq?: string; + /** + * Address that deployed the contract (filter: ne) + */ + deployer_ne?: string; + /** + * Address that deployed the contract (filter: contains) + */ + deployer_contains?: string; + /** + * Address that deployed the contract (filter: starts_with) + */ + deployer_starts_with?: string; + /** + * Address that deployed the contract (filter: ends_with) + */ + deployer_ends_with?: string; + /** + * Address that deployed the contract (filter: like) + */ + deployer_like?: string; + /** + * Address that deployed the contract (filter: not_like) + */ + deployer_not_like?: string; + /** + * Address that deployed the contract (filter: in_values) (comma-separated list) + */ + deployer_in_values?: string; + /** + * Address that deployed the contract (filter: not_in_values) (comma-separated list) + */ + deployer_not_in_values?: string; + /** + * Factory contract address if applicable (filter: eq) + */ + factory_eq?: string; + /** + * Factory contract address if applicable (filter: ne) + */ + factory_ne?: string; + /** + * Factory contract address if applicable (filter: contains) + */ + factory_contains?: string; + /** + * Factory contract address if applicable (filter: starts_with) + */ + factory_starts_with?: string; + /** + * Factory contract address if applicable (filter: ends_with) + */ + factory_ends_with?: string; + /** + * Factory contract address if applicable (filter: like) + */ + factory_like?: string; + /** + * Factory contract address if applicable (filter: not_like) + */ + factory_not_like?: string; + /** + * Factory contract address if applicable (filter: in_values) (comma-separated list) + */ + factory_in_values?: string; + /** + * Factory contract address if applicable (filter: not_in_values) (comma-separated list) + */ + factory_not_in_values?: string; + /** + * Hash of the initialization code (filter: eq) + */ + init_code_hash_eq?: string; + /** + * Hash of the initialization code (filter: ne) + */ + init_code_hash_ne?: string; + /** + * Hash of the initialization code (filter: contains) + */ + init_code_hash_contains?: string; + /** + * Hash of the initialization code (filter: starts_with) + */ + init_code_hash_starts_with?: string; + /** + * Hash of the initialization code (filter: ends_with) + */ + init_code_hash_ends_with?: string; + /** + * Hash of the initialization code (filter: like) + */ + init_code_hash_like?: string; + /** + * Hash of the initialization code (filter: not_like) + */ + init_code_hash_not_like?: string; + /** + * Hash of the initialization code (filter: in_values) (comma-separated list) + */ + init_code_hash_in_values?: string; + /** + * Hash of the initialization code (filter: not_in_values) (comma-separated list) + */ + init_code_hash_not_in_values?: string; + /** + * The maximum number of int_contract_creation to return. If unspecified, at most 100 items will be returned. The maximum value is 10000; values above 10000 will be coerced to 10000. + */ + page_size?: number; + /** + * A page token, received from a previous `ListIntContractCreation` call. Provide this to retrieve the subsequent page. + */ + page_token?: string; + /** + * The order of results. Format: comma-separated list of fields. Example: "foo,bar" or "foo desc,bar" for descending order on foo. If unspecified, results will be returned in the default order. + */ + order_by?: string; + }; + url: '/api/v1/int_contract_creation'; +}; + +export type IntContractCreationServiceListErrors = { + /** + * Default error response + */ + default: Status; +}; + +export type IntContractCreationServiceListError = + IntContractCreationServiceListErrors[keyof IntContractCreationServiceListErrors]; + +export type IntContractCreationServiceListResponses = { + /** + * OK + */ + 200: ListIntContractCreationResponse; +}; + +export type IntContractCreationServiceListResponse = + IntContractCreationServiceListResponses[keyof IntContractCreationServiceListResponses]; + +export type IntContractCreationServiceGetData = { + body?: never; + path: { + /** + * Block where contract was created + */ + block_number: number; + }; + query?: never; + url: '/api/v1/int_contract_creation/{block_number}'; +}; + +export type IntContractCreationServiceGetErrors = { + /** + * Default error response + */ + default: Status; +}; + +export type IntContractCreationServiceGetError = + IntContractCreationServiceGetErrors[keyof IntContractCreationServiceGetErrors]; + +export type IntContractCreationServiceGetResponses = { + /** + * OK + */ + 200: GetIntContractCreationResponse; +}; + +export type IntContractCreationServiceGetResponse = + IntContractCreationServiceGetResponses[keyof IntContractCreationServiceGetResponses]; + +export type IntContractSelfdestructServiceListData = { + body?: never; + path?: never; + query?: { + /** + * Block where SELFDESTRUCT occurred (filter: eq) + */ + block_number_eq?: number; + /** + * Block where SELFDESTRUCT occurred (filter: ne) + */ + block_number_ne?: number; + /** + * Block where SELFDESTRUCT occurred (filter: lt) + */ + block_number_lt?: number; + /** + * Block where SELFDESTRUCT occurred (filter: lte) + */ + block_number_lte?: number; + /** + * Block where SELFDESTRUCT occurred (filter: gt) + */ + block_number_gt?: number; + /** + * Block where SELFDESTRUCT occurred (filter: gte) + */ + block_number_gte?: number; + /** + * Block where SELFDESTRUCT occurred (filter: between_min) + */ + block_number_between_min?: number; + /** + * Block where SELFDESTRUCT occurred (filter: between_max_value) + */ + block_number_between_max_value?: number; + /** + * Block where SELFDESTRUCT occurred (filter: in_values) (comma-separated list) + */ + block_number_in_values?: string; + /** + * Block where SELFDESTRUCT occurred (filter: not_in_values) (comma-separated list) + */ + block_number_not_in_values?: string; + /** + * Position in block (filter: eq) + */ + transaction_index_eq?: number; + /** + * Position in block (filter: ne) + */ + transaction_index_ne?: number; + /** + * Position in block (filter: lt) + */ + transaction_index_lt?: number; + /** + * Position in block (filter: lte) + */ + transaction_index_lte?: number; + /** + * Position in block (filter: gt) + */ + transaction_index_gt?: number; + /** + * Position in block (filter: gte) + */ + transaction_index_gte?: number; + /** + * Position in block (filter: between_min) + */ + transaction_index_between_min?: number; + /** + * Position in block (filter: between_max_value) + */ + transaction_index_between_max_value?: number; + /** + * Position in block (filter: in_values) (comma-separated list) + */ + transaction_index_in_values?: string; + /** + * Position in block (filter: not_in_values) (comma-separated list) + */ + transaction_index_not_in_values?: string; + /** + * Position within transaction traces (filter: eq) + */ + internal_index_eq?: number; + /** + * Position within transaction traces (filter: ne) + */ + internal_index_ne?: number; + /** + * Position within transaction traces (filter: lt) + */ + internal_index_lt?: number; + /** + * Position within transaction traces (filter: lte) + */ + internal_index_lte?: number; + /** + * Position within transaction traces (filter: gt) + */ + internal_index_gt?: number; + /** + * Position within transaction traces (filter: gte) + */ + internal_index_gte?: number; + /** + * Position within transaction traces (filter: between_min) + */ + internal_index_between_min?: number; + /** + * Position within transaction traces (filter: between_max_value) + */ + internal_index_between_max_value?: number; + /** + * Position within transaction traces (filter: in_values) (comma-separated list) + */ + internal_index_in_values?: string; + /** + * Position within transaction traces (filter: not_in_values) (comma-separated list) + */ + internal_index_not_in_values?: string; + /** + * Contract that was destroyed (filter: eq) + */ + address_eq?: string; + /** + * Contract that was destroyed (filter: ne) + */ + address_ne?: string; + /** + * Contract that was destroyed (filter: contains) + */ + address_contains?: string; + /** + * Contract that was destroyed (filter: starts_with) + */ + address_starts_with?: string; + /** + * Contract that was destroyed (filter: ends_with) + */ + address_ends_with?: string; + /** + * Contract that was destroyed (filter: like) + */ + address_like?: string; + /** + * Contract that was destroyed (filter: not_like) + */ + address_not_like?: string; + /** + * Contract that was destroyed (filter: in_values) (comma-separated list) + */ + address_in_values?: string; + /** + * Contract that was destroyed (filter: not_in_values) (comma-separated list) + */ + address_not_in_values?: string; + /** + * Timestamp when the record was last updated (filter: eq) + */ + updated_date_time_eq?: number; + /** + * Timestamp when the record was last updated (filter: ne) + */ + updated_date_time_ne?: number; + /** + * Timestamp when the record was last updated (filter: lt) + */ + updated_date_time_lt?: number; + /** + * Timestamp when the record was last updated (filter: lte) + */ + updated_date_time_lte?: number; + /** + * Timestamp when the record was last updated (filter: gt) + */ + updated_date_time_gt?: number; + /** + * Timestamp when the record was last updated (filter: gte) + */ + updated_date_time_gte?: number; + /** + * Timestamp when the record was last updated (filter: between_min) + */ + updated_date_time_between_min?: number; + /** + * Timestamp when the record was last updated (filter: between_max_value) + */ + updated_date_time_between_max_value?: number; + /** + * Timestamp when the record was last updated (filter: in_values) (comma-separated list) + */ + updated_date_time_in_values?: string; + /** + * Timestamp when the record was last updated (filter: not_in_values) (comma-separated list) + */ + updated_date_time_not_in_values?: string; + /** + * Transaction hash (filter: eq) + */ + transaction_hash_eq?: string; + /** + * Transaction hash (filter: ne) + */ + transaction_hash_ne?: string; + /** + * Transaction hash (filter: contains) + */ + transaction_hash_contains?: string; + /** + * Transaction hash (filter: starts_with) + */ + transaction_hash_starts_with?: string; + /** + * Transaction hash (filter: ends_with) + */ + transaction_hash_ends_with?: string; + /** + * Transaction hash (filter: like) + */ + transaction_hash_like?: string; + /** + * Transaction hash (filter: not_like) + */ + transaction_hash_not_like?: string; + /** + * Transaction hash (filter: in_values) (comma-separated list) + */ + transaction_hash_in_values?: string; + /** + * Transaction hash (filter: not_in_values) (comma-separated list) + */ + transaction_hash_not_in_values?: string; + /** + * Address receiving the ETH (filter: eq) + */ + beneficiary_eq?: string; + /** + * Address receiving the ETH (filter: ne) + */ + beneficiary_ne?: string; + /** + * Address receiving the ETH (filter: contains) + */ + beneficiary_contains?: string; + /** + * Address receiving the ETH (filter: starts_with) + */ + beneficiary_starts_with?: string; + /** + * Address receiving the ETH (filter: ends_with) + */ + beneficiary_ends_with?: string; + /** + * Address receiving the ETH (filter: like) + */ + beneficiary_like?: string; + /** + * Address receiving the ETH (filter: not_like) + */ + beneficiary_not_like?: string; + /** + * Address receiving the ETH (filter: in_values) (comma-separated list) + */ + beneficiary_in_values?: string; + /** + * Address receiving the ETH (filter: not_in_values) (comma-separated list) + */ + beneficiary_not_in_values?: string; + /** + * Amount of ETH sent to beneficiary (filter: eq) + */ + value_transferred_eq?: string; + /** + * Amount of ETH sent to beneficiary (filter: ne) + */ + value_transferred_ne?: string; + /** + * Amount of ETH sent to beneficiary (filter: contains) + */ + value_transferred_contains?: string; + /** + * Amount of ETH sent to beneficiary (filter: starts_with) + */ + value_transferred_starts_with?: string; + /** + * Amount of ETH sent to beneficiary (filter: ends_with) + */ + value_transferred_ends_with?: string; + /** + * Amount of ETH sent to beneficiary (filter: like) + */ + value_transferred_like?: string; + /** + * Amount of ETH sent to beneficiary (filter: not_like) + */ + value_transferred_not_like?: string; + /** + * Amount of ETH sent to beneficiary (filter: in_values) (comma-separated list) + */ + value_transferred_in_values?: string; + /** + * Amount of ETH sent to beneficiary (filter: not_in_values) (comma-separated list) + */ + value_transferred_not_in_values?: string; + /** + * True if contract was created and destroyed in the same transaction - storage always cleared per EIP-6780 (filter: eq) + */ + ephemeral_eq?: boolean; + /** + * True if contract was created and destroyed in the same transaction - storage always cleared per EIP-6780 (filter: ne) + */ + ephemeral_ne?: boolean; + /** + * True if storage was cleared (pre-Shanghai OR ephemeral) (filter: eq) + */ + storage_cleared_eq?: boolean; + /** + * True if storage was cleared (pre-Shanghai OR ephemeral) (filter: ne) + */ + storage_cleared_ne?: boolean; + /** + * Block where contract was created (if known) (filter: eq) + */ + creation_block_eq?: number; + /** + * Block where contract was created (if known) (filter: ne) + */ + creation_block_ne?: number; + /** + * Block where contract was created (if known) (filter: lt) + */ + creation_block_lt?: number; + /** + * Block where contract was created (if known) (filter: lte) + */ + creation_block_lte?: number; + /** + * Block where contract was created (if known) (filter: gt) + */ + creation_block_gt?: number; + /** + * Block where contract was created (if known) (filter: gte) + */ + creation_block_gte?: number; + /** + * Block where contract was created (if known) (filter: between_min) + */ + creation_block_between_min?: number; + /** + * Block where contract was created (if known) (filter: between_max_value) + */ + creation_block_between_max_value?: number; + /** + * Block where contract was created (if known) (filter: in_values) (comma-separated list) + */ + creation_block_in_values?: string; + /** + * Block where contract was created (if known) (filter: not_in_values) (comma-separated list) + */ + creation_block_not_in_values?: string; + /** + * Transaction that created the contract (if known) (filter: eq) + */ + creation_transaction_hash_eq?: string; + /** + * Transaction that created the contract (if known) (filter: ne) + */ + creation_transaction_hash_ne?: string; + /** + * Transaction that created the contract (if known) (filter: contains) + */ + creation_transaction_hash_contains?: string; + /** + * Transaction that created the contract (if known) (filter: starts_with) + */ + creation_transaction_hash_starts_with?: string; + /** + * Transaction that created the contract (if known) (filter: ends_with) + */ + creation_transaction_hash_ends_with?: string; + /** + * Transaction that created the contract (if known) (filter: like) + */ + creation_transaction_hash_like?: string; + /** + * Transaction that created the contract (if known) (filter: not_like) + */ + creation_transaction_hash_not_like?: string; + /** + * Transaction that created the contract (if known) (filter: in_values) (comma-separated list) + */ + creation_transaction_hash_in_values?: string; + /** + * Transaction that created the contract (if known) (filter: not_in_values) (comma-separated list) + */ + creation_transaction_hash_not_in_values?: string; + /** + * The maximum number of int_contract_selfdestruct to return. If unspecified, at most 100 items will be returned. The maximum value is 10000; values above 10000 will be coerced to 10000. + */ + page_size?: number; + /** + * A page token, received from a previous `ListIntContractSelfdestruct` call. Provide this to retrieve the subsequent page. + */ + page_token?: string; + /** + * The order of results. Format: comma-separated list of fields. Example: "foo,bar" or "foo desc,bar" for descending order on foo. If unspecified, results will be returned in the default order. + */ + order_by?: string; + }; + url: '/api/v1/int_contract_selfdestruct'; +}; + +export type IntContractSelfdestructServiceListErrors = { + /** + * Default error response + */ + default: Status; +}; + +export type IntContractSelfdestructServiceListError = + IntContractSelfdestructServiceListErrors[keyof IntContractSelfdestructServiceListErrors]; + +export type IntContractSelfdestructServiceListResponses = { + /** + * OK + */ + 200: ListIntContractSelfdestructResponse; +}; + +export type IntContractSelfdestructServiceListResponse = + IntContractSelfdestructServiceListResponses[keyof IntContractSelfdestructServiceListResponses]; + +export type IntContractSelfdestructServiceGetData = { + body?: never; + path: { + /** + * Block where SELFDESTRUCT occurred + */ + block_number: number; + }; + query?: never; + url: '/api/v1/int_contract_selfdestruct/{block_number}'; +}; + +export type IntContractSelfdestructServiceGetErrors = { + /** + * Default error response + */ + default: Status; +}; + +export type IntContractSelfdestructServiceGetError = + IntContractSelfdestructServiceGetErrors[keyof IntContractSelfdestructServiceGetErrors]; + +export type IntContractSelfdestructServiceGetResponses = { + /** + * OK + */ + 200: GetIntContractSelfdestructResponse; +}; + +export type IntContractSelfdestructServiceGetResponse = + IntContractSelfdestructServiceGetResponses[keyof IntContractSelfdestructServiceGetResponses]; + export type IntContractStorageExpiry1mServiceListData = { body?: never; path?: never; @@ -80445,7 +82069,7 @@ export type IntEngineNewPayloadServiceGetResponses = { export type IntEngineNewPayloadServiceGetResponse = IntEngineNewPayloadServiceGetResponses[keyof IntEngineNewPayloadServiceGetResponses]; -export type IntEngineNewPayloadFastestServiceListData = { +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceListData = { body?: never; path?: never; query?: { @@ -80870,11 +82494,11 @@ export type IntEngineNewPayloadFastestServiceListData = { */ meta_client_name_not_in_values?: string; /** - * The maximum number of int_engine_new_payload_fastest to return. If unspecified, at most 100 items will be returned. The maximum value is 10000; values above 10000 will be coerced to 10000. + * The maximum number of int_engine_new_payload_fastest_execution_by_node_class to return. If unspecified, at most 100 items will be returned. The maximum value is 10000; values above 10000 will be coerced to 10000. */ page_size?: number; /** - * A page token, received from a previous `ListIntEngineNewPayloadFastest` call. Provide this to retrieve the subsequent page. + * A page token, received from a previous `ListIntEngineNewPayloadFastestExecutionByNodeClass` call. Provide this to retrieve the subsequent page. */ page_token?: string; /** @@ -80882,30 +82506,30 @@ export type IntEngineNewPayloadFastestServiceListData = { */ order_by?: string; }; - url: '/api/v1/int_engine_new_payload_fastest'; + url: '/api/v1/int_engine_new_payload_fastest_execution_by_node_class'; }; -export type IntEngineNewPayloadFastestServiceListErrors = { +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceListErrors = { /** * Default error response */ default: Status; }; -export type IntEngineNewPayloadFastestServiceListError = - IntEngineNewPayloadFastestServiceListErrors[keyof IntEngineNewPayloadFastestServiceListErrors]; +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceListError = + IntEngineNewPayloadFastestExecutionByNodeClassServiceListErrors[keyof IntEngineNewPayloadFastestExecutionByNodeClassServiceListErrors]; -export type IntEngineNewPayloadFastestServiceListResponses = { +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponses = { /** * OK */ - 200: ListIntEngineNewPayloadFastestResponse; + 200: ListIntEngineNewPayloadFastestExecutionByNodeClassResponse; }; -export type IntEngineNewPayloadFastestServiceListResponse = - IntEngineNewPayloadFastestServiceListResponses[keyof IntEngineNewPayloadFastestServiceListResponses]; +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponse = + IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponses[keyof IntEngineNewPayloadFastestExecutionByNodeClassServiceListResponses]; -export type IntEngineNewPayloadFastestServiceGetData = { +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceGetData = { body?: never; path: { /** @@ -80914,28 +82538,28 @@ export type IntEngineNewPayloadFastestServiceGetData = { slot_start_date_time: number; }; query?: never; - url: '/api/v1/int_engine_new_payload_fastest/{slot_start_date_time}'; + url: '/api/v1/int_engine_new_payload_fastest_execution_by_node_class/{slot_start_date_time}'; }; -export type IntEngineNewPayloadFastestServiceGetErrors = { +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceGetErrors = { /** * Default error response */ default: Status; }; -export type IntEngineNewPayloadFastestServiceGetError = - IntEngineNewPayloadFastestServiceGetErrors[keyof IntEngineNewPayloadFastestServiceGetErrors]; +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceGetError = + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetErrors[keyof IntEngineNewPayloadFastestExecutionByNodeClassServiceGetErrors]; -export type IntEngineNewPayloadFastestServiceGetResponses = { +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponses = { /** * OK */ - 200: GetIntEngineNewPayloadFastestResponse; + 200: GetIntEngineNewPayloadFastestExecutionByNodeClassResponse; }; -export type IntEngineNewPayloadFastestServiceGetResponse = - IntEngineNewPayloadFastestServiceGetResponses[keyof IntEngineNewPayloadFastestServiceGetResponses]; +export type IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponse = + IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponses[keyof IntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponses]; export type IntExecutionBlockByDateServiceListData = { body?: never; @@ -81129,6 +82753,418 @@ export type IntExecutionBlockByDateServiceGetResponses = { export type IntExecutionBlockByDateServiceGetResponse = IntExecutionBlockByDateServiceGetResponses[keyof IntExecutionBlockByDateServiceGetResponses]; +export type IntStorageSelfdestructDiffsServiceListData = { + body?: never; + path?: never; + query?: { + /** + * Block where SELFDESTRUCT occurred (filter: eq) + */ + block_number_eq?: number; + /** + * Block where SELFDESTRUCT occurred (filter: ne) + */ + block_number_ne?: number; + /** + * Block where SELFDESTRUCT occurred (filter: lt) + */ + block_number_lt?: number; + /** + * Block where SELFDESTRUCT occurred (filter: lte) + */ + block_number_lte?: number; + /** + * Block where SELFDESTRUCT occurred (filter: gt) + */ + block_number_gt?: number; + /** + * Block where SELFDESTRUCT occurred (filter: gte) + */ + block_number_gte?: number; + /** + * Block where SELFDESTRUCT occurred (filter: between_min) + */ + block_number_between_min?: number; + /** + * Block where SELFDESTRUCT occurred (filter: between_max_value) + */ + block_number_between_max_value?: number; + /** + * Block where SELFDESTRUCT occurred (filter: in_values) (comma-separated list) + */ + block_number_in_values?: string; + /** + * Block where SELFDESTRUCT occurred (filter: not_in_values) (comma-separated list) + */ + block_number_not_in_values?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: eq) + */ + transaction_hash_eq?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: ne) + */ + transaction_hash_ne?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: contains) + */ + transaction_hash_contains?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: starts_with) + */ + transaction_hash_starts_with?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: ends_with) + */ + transaction_hash_ends_with?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: like) + */ + transaction_hash_like?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: not_like) + */ + transaction_hash_not_like?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: in_values) (comma-separated list) + */ + transaction_hash_in_values?: string; + /** + * Transaction hash of the SELFDESTRUCT (filter: not_in_values) (comma-separated list) + */ + transaction_hash_not_in_values?: string; + /** + * Internal index of the SELFDESTRUCT trace (filter: eq) + */ + internal_index_eq?: number; + /** + * Internal index of the SELFDESTRUCT trace (filter: ne) + */ + internal_index_ne?: number; + /** + * Internal index of the SELFDESTRUCT trace (filter: lt) + */ + internal_index_lt?: number; + /** + * Internal index of the SELFDESTRUCT trace (filter: lte) + */ + internal_index_lte?: number; + /** + * Internal index of the SELFDESTRUCT trace (filter: gt) + */ + internal_index_gt?: number; + /** + * Internal index of the SELFDESTRUCT trace (filter: gte) + */ + internal_index_gte?: number; + /** + * Internal index of the SELFDESTRUCT trace (filter: between_min) + */ + internal_index_between_min?: number; + /** + * Internal index of the SELFDESTRUCT trace (filter: between_max_value) + */ + internal_index_between_max_value?: number; + /** + * Internal index of the SELFDESTRUCT trace (filter: in_values) (comma-separated list) + */ + internal_index_in_values?: string; + /** + * Internal index of the SELFDESTRUCT trace (filter: not_in_values) (comma-separated list) + */ + internal_index_not_in_values?: string; + /** + * Storage slot key being cleared (filter: eq) + */ + slot_eq?: string; + /** + * Storage slot key being cleared (filter: ne) + */ + slot_ne?: string; + /** + * Storage slot key being cleared (filter: contains) + */ + slot_contains?: string; + /** + * Storage slot key being cleared (filter: starts_with) + */ + slot_starts_with?: string; + /** + * Storage slot key being cleared (filter: ends_with) + */ + slot_ends_with?: string; + /** + * Storage slot key being cleared (filter: like) + */ + slot_like?: string; + /** + * Storage slot key being cleared (filter: not_like) + */ + slot_not_like?: string; + /** + * Storage slot key being cleared (filter: in_values) (comma-separated list) + */ + slot_in_values?: string; + /** + * Storage slot key being cleared (filter: not_in_values) (comma-separated list) + */ + slot_not_in_values?: string; + /** + * Timestamp when the record was last updated (filter: eq) + */ + updated_date_time_eq?: number; + /** + * Timestamp when the record was last updated (filter: ne) + */ + updated_date_time_ne?: number; + /** + * Timestamp when the record was last updated (filter: lt) + */ + updated_date_time_lt?: number; + /** + * Timestamp when the record was last updated (filter: lte) + */ + updated_date_time_lte?: number; + /** + * Timestamp when the record was last updated (filter: gt) + */ + updated_date_time_gt?: number; + /** + * Timestamp when the record was last updated (filter: gte) + */ + updated_date_time_gte?: number; + /** + * Timestamp when the record was last updated (filter: between_min) + */ + updated_date_time_between_min?: number; + /** + * Timestamp when the record was last updated (filter: between_max_value) + */ + updated_date_time_between_max_value?: number; + /** + * Timestamp when the record was last updated (filter: in_values) (comma-separated list) + */ + updated_date_time_in_values?: string; + /** + * Timestamp when the record was last updated (filter: not_in_values) (comma-separated list) + */ + updated_date_time_not_in_values?: string; + /** + * Transaction index within the block (filter: eq) + */ + transaction_index_eq?: number; + /** + * Transaction index within the block (filter: ne) + */ + transaction_index_ne?: number; + /** + * Transaction index within the block (filter: lt) + */ + transaction_index_lt?: number; + /** + * Transaction index within the block (filter: lte) + */ + transaction_index_lte?: number; + /** + * Transaction index within the block (filter: gt) + */ + transaction_index_gt?: number; + /** + * Transaction index within the block (filter: gte) + */ + transaction_index_gte?: number; + /** + * Transaction index within the block (filter: between_min) + */ + transaction_index_between_min?: number; + /** + * Transaction index within the block (filter: between_max_value) + */ + transaction_index_between_max_value?: number; + /** + * Transaction index within the block (filter: in_values) (comma-separated list) + */ + transaction_index_in_values?: string; + /** + * Transaction index within the block (filter: not_in_values) (comma-separated list) + */ + transaction_index_not_in_values?: string; + /** + * Contract address that was selfdestructed (filter: eq) + */ + address_eq?: string; + /** + * Contract address that was selfdestructed (filter: ne) + */ + address_ne?: string; + /** + * Contract address that was selfdestructed (filter: contains) + */ + address_contains?: string; + /** + * Contract address that was selfdestructed (filter: starts_with) + */ + address_starts_with?: string; + /** + * Contract address that was selfdestructed (filter: ends_with) + */ + address_ends_with?: string; + /** + * Contract address that was selfdestructed (filter: like) + */ + address_like?: string; + /** + * Contract address that was selfdestructed (filter: not_like) + */ + address_not_like?: string; + /** + * Contract address that was selfdestructed (filter: in_values) (comma-separated list) + */ + address_in_values?: string; + /** + * Contract address that was selfdestructed (filter: not_in_values) (comma-separated list) + */ + address_not_in_values?: string; + /** + * Value before clearing (last known value) (filter: eq) + */ + from_value_eq?: string; + /** + * Value before clearing (last known value) (filter: ne) + */ + from_value_ne?: string; + /** + * Value before clearing (last known value) (filter: contains) + */ + from_value_contains?: string; + /** + * Value before clearing (last known value) (filter: starts_with) + */ + from_value_starts_with?: string; + /** + * Value before clearing (last known value) (filter: ends_with) + */ + from_value_ends_with?: string; + /** + * Value before clearing (last known value) (filter: like) + */ + from_value_like?: string; + /** + * Value before clearing (last known value) (filter: not_like) + */ + from_value_not_like?: string; + /** + * Value before clearing (last known value) (filter: in_values) (comma-separated list) + */ + from_value_in_values?: string; + /** + * Value before clearing (last known value) (filter: not_in_values) (comma-separated list) + */ + from_value_not_in_values?: string; + /** + * Value after clearing (always 0x00...00) (filter: eq) + */ + to_value_eq?: string; + /** + * Value after clearing (always 0x00...00) (filter: ne) + */ + to_value_ne?: string; + /** + * Value after clearing (always 0x00...00) (filter: contains) + */ + to_value_contains?: string; + /** + * Value after clearing (always 0x00...00) (filter: starts_with) + */ + to_value_starts_with?: string; + /** + * Value after clearing (always 0x00...00) (filter: ends_with) + */ + to_value_ends_with?: string; + /** + * Value after clearing (always 0x00...00) (filter: like) + */ + to_value_like?: string; + /** + * Value after clearing (always 0x00...00) (filter: not_like) + */ + to_value_not_like?: string; + /** + * Value after clearing (always 0x00...00) (filter: in_values) (comma-separated list) + */ + to_value_in_values?: string; + /** + * Value after clearing (always 0x00...00) (filter: not_in_values) (comma-separated list) + */ + to_value_not_in_values?: string; + /** + * The maximum number of int_storage_selfdestruct_diffs to return. If unspecified, at most 100 items will be returned. The maximum value is 10000; values above 10000 will be coerced to 10000. + */ + page_size?: number; + /** + * A page token, received from a previous `ListIntStorageSelfdestructDiffs` call. Provide this to retrieve the subsequent page. + */ + page_token?: string; + /** + * The order of results. Format: comma-separated list of fields. Example: "foo,bar" or "foo desc,bar" for descending order on foo. If unspecified, results will be returned in the default order. + */ + order_by?: string; + }; + url: '/api/v1/int_storage_selfdestruct_diffs'; +}; + +export type IntStorageSelfdestructDiffsServiceListErrors = { + /** + * Default error response + */ + default: Status; +}; + +export type IntStorageSelfdestructDiffsServiceListError = + IntStorageSelfdestructDiffsServiceListErrors[keyof IntStorageSelfdestructDiffsServiceListErrors]; + +export type IntStorageSelfdestructDiffsServiceListResponses = { + /** + * OK + */ + 200: ListIntStorageSelfdestructDiffsResponse; +}; + +export type IntStorageSelfdestructDiffsServiceListResponse = + IntStorageSelfdestructDiffsServiceListResponses[keyof IntStorageSelfdestructDiffsServiceListResponses]; + +export type IntStorageSelfdestructDiffsServiceGetData = { + body?: never; + path: { + /** + * Block where SELFDESTRUCT occurred + */ + block_number: number; + }; + query?: never; + url: '/api/v1/int_storage_selfdestruct_diffs/{block_number}'; +}; + +export type IntStorageSelfdestructDiffsServiceGetErrors = { + /** + * Default error response + */ + default: Status; +}; + +export type IntStorageSelfdestructDiffsServiceGetError = + IntStorageSelfdestructDiffsServiceGetErrors[keyof IntStorageSelfdestructDiffsServiceGetErrors]; + +export type IntStorageSelfdestructDiffsServiceGetResponses = { + /** + * OK + */ + 200: GetIntStorageSelfdestructDiffsResponse; +}; + +export type IntStorageSelfdestructDiffsServiceGetResponse = + IntStorageSelfdestructDiffsServiceGetResponses[keyof IntStorageSelfdestructDiffsServiceGetResponses]; + export type IntStorageSlotDiffServiceListData = { body?: never; path?: never; diff --git a/src/api/zod.gen.ts b/src/api/zod.gen.ts index 44cd58548..8629aa971 100644 --- a/src/api/zod.gen.ts +++ b/src/api/zod.gen.ts @@ -6631,6 +6631,73 @@ export const zFctNodeActiveLast24h = z.object({ username: z.optional(z.string()), }); +export const zFctNodeCpuUtilization = z.object({ + client_type: z.optional(z.string()), + max_core_pct: z.optional(z.number()), + max_single_core_pct: z.optional(z.number()), + mean_core_pct: z.optional(z.number()), + meta_client_name: z.optional(z.string()), + meta_network_name: z.optional(z.string()), + min_core_pct: z.optional(z.number()), + node_class: z.optional(z.string()), + pid: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_start_date_time: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), +}); + export const zFctOpcodeGasByOpcodeDaily = z.object({ avg_count_per_block: z.optional(z.number()), avg_gas_per_block: z.optional(z.number()), @@ -8582,6 +8649,13 @@ export const zGetFctNodeActiveLast24hResponse = z.object({ item: z.optional(zFctNodeActiveLast24h), }); +/** + * Response for getting a single fct_node_cpu_utilization record + */ +export const zGetFctNodeCpuUtilizationResponse = z.object({ + item: z.optional(zFctNodeCpuUtilization), +}); + /** * Response for getting a single fct_opcode_gas_by_opcode_daily record */ @@ -9692,18 +9766,7 @@ export const zGetIntBlockProposerCanonicalResponse = z.object({ item: z.optional(zIntBlockProposerCanonical), }); -export const zIntContractStorageExpiry1m = z.object({ - active_slots: z.optional( - z.coerce - .bigint() - .check( - z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), - z.maximum(BigInt('18446744073709551615'), { - error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', - }) - ) - ), - address: z.optional(z.string()), +export const zIntContractCreation = z.object({ block_number: z.optional( z .int() @@ -9712,17 +9775,20 @@ export const zIntContractStorageExpiry1m = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - effective_bytes: z.optional( - z.coerce - .bigint() + contract_address: z.optional(z.string()), + deployer: z.optional(z.string()), + factory: z.optional(z.string()), + init_code_hash: z.optional(z.string()), + internal_index: z.optional( + z + .int() .check( - z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), - z.maximum(BigInt('18446744073709551615'), { - error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', - }) + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - touch_block: z.optional( + transaction_hash: z.optional(z.string()), + transaction_index: z.optional( z .int() .check( @@ -9741,24 +9807,15 @@ export const zIntContractStorageExpiry1m = z.object({ }); /** - * Response for getting a single int_contract_storage_expiry_1m record + * Response for getting a single int_contract_creation record */ -export const zGetIntContractStorageExpiry1mResponse = z.object({ - item: z.optional(zIntContractStorageExpiry1m), +export const zGetIntContractCreationResponse = z.object({ + item: z.optional(zIntContractCreation), }); -export const zIntContractStorageExpiry6m = z.object({ - active_slots: z.optional( - z.coerce - .bigint() - .check( - z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), - z.maximum(BigInt('18446744073709551615'), { - error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', - }) - ) - ), +export const zIntContractSelfdestruct = z.object({ address: z.optional(z.string()), + beneficiary: z.optional(z.string()), block_number: z.optional( z .int() @@ -9767,17 +9824,30 @@ export const zIntContractStorageExpiry6m = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - effective_bytes: z.optional( - z.coerce - .bigint() + creation_block: z.optional( + z.union([ + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ), + z.null(), + ]) + ), + creation_transaction_hash: z.optional(z.union([z.string(), z.null()])), + ephemeral: z.optional(z.boolean()), + internal_index: z.optional( + z + .int() .check( - z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), - z.maximum(BigInt('18446744073709551615'), { - error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', - }) + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - touch_block: z.optional( + storage_cleared: z.optional(z.boolean()), + transaction_hash: z.optional(z.string()), + transaction_index: z.optional( z .int() .check( @@ -9793,16 +9863,17 @@ export const zIntContractStorageExpiry6m = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), + value_transferred: z.optional(z.string()), }); /** - * Response for getting a single int_contract_storage_expiry_6m record + * Response for getting a single int_contract_selfdestruct record */ -export const zGetIntContractStorageExpiry6mResponse = z.object({ - item: z.optional(zIntContractStorageExpiry6m), +export const zGetIntContractSelfdestructResponse = z.object({ + item: z.optional(zIntContractSelfdestruct), }); -export const zIntContractStorageExpiry12m = z.object({ +export const zIntContractStorageExpiry1m = z.object({ active_slots: z.optional( z.coerce .bigint() @@ -9851,13 +9922,13 @@ export const zIntContractStorageExpiry12m = z.object({ }); /** - * Response for getting a single int_contract_storage_expiry_12m record + * Response for getting a single int_contract_storage_expiry_1m record */ -export const zGetIntContractStorageExpiry12mResponse = z.object({ - item: z.optional(zIntContractStorageExpiry12m), +export const zGetIntContractStorageExpiry1mResponse = z.object({ + item: z.optional(zIntContractStorageExpiry1m), }); -export const zIntContractStorageExpiry18m = z.object({ +export const zIntContractStorageExpiry6m = z.object({ active_slots: z.optional( z.coerce .bigint() @@ -9906,13 +9977,13 @@ export const zIntContractStorageExpiry18m = z.object({ }); /** - * Response for getting a single int_contract_storage_expiry_18m record + * Response for getting a single int_contract_storage_expiry_6m record */ -export const zGetIntContractStorageExpiry18mResponse = z.object({ - item: z.optional(zIntContractStorageExpiry18m), +export const zGetIntContractStorageExpiry6mResponse = z.object({ + item: z.optional(zIntContractStorageExpiry6m), }); -export const zIntContractStorageExpiry24m = z.object({ +export const zIntContractStorageExpiry12m = z.object({ active_slots: z.optional( z.coerce .bigint() @@ -9961,51 +10032,13 @@ export const zIntContractStorageExpiry24m = z.object({ }); /** - * Response for getting a single int_contract_storage_expiry_24m record - */ -export const zGetIntContractStorageExpiry24mResponse = z.object({ - item: z.optional(zIntContractStorageExpiry24m), -}); - -export const zIntContractStorageNextTouch = z.object({ - address: z.optional(z.string()), - block_number: z.optional( - z - .int() - .check( - z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), - z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) - ) - ), - next_touch_block: z.optional( - z.union([ - z - .int() - .check( - z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), - z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) - ), - z.null(), - ]) - ), - updated_date_time: z.optional( - z - .int() - .check( - z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), - z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) - ) - ), -}); - -/** - * Response for getting a single int_contract_storage_next_touch record + * Response for getting a single int_contract_storage_expiry_12m record */ -export const zGetIntContractStorageNextTouchResponse = z.object({ - item: z.optional(zIntContractStorageNextTouch), +export const zGetIntContractStorageExpiry12mResponse = z.object({ + item: z.optional(zIntContractStorageExpiry12m), }); -export const zIntContractStorageReactivation1m = z.object({ +export const zIntContractStorageExpiry18m = z.object({ active_slots: z.optional( z.coerce .bigint() @@ -10054,13 +10087,13 @@ export const zIntContractStorageReactivation1m = z.object({ }); /** - * Response for getting a single int_contract_storage_reactivation_1m record + * Response for getting a single int_contract_storage_expiry_18m record */ -export const zGetIntContractStorageReactivation1mResponse = z.object({ - item: z.optional(zIntContractStorageReactivation1m), +export const zGetIntContractStorageExpiry18mResponse = z.object({ + item: z.optional(zIntContractStorageExpiry18m), }); -export const zIntContractStorageReactivation6m = z.object({ +export const zIntContractStorageExpiry24m = z.object({ active_slots: z.optional( z.coerce .bigint() @@ -10109,23 +10142,13 @@ export const zIntContractStorageReactivation6m = z.object({ }); /** - * Response for getting a single int_contract_storage_reactivation_6m record + * Response for getting a single int_contract_storage_expiry_24m record */ -export const zGetIntContractStorageReactivation6mResponse = z.object({ - item: z.optional(zIntContractStorageReactivation6m), +export const zGetIntContractStorageExpiry24mResponse = z.object({ + item: z.optional(zIntContractStorageExpiry24m), }); -export const zIntContractStorageReactivation12m = z.object({ - active_slots: z.optional( - z.coerce - .bigint() - .check( - z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), - z.maximum(BigInt('18446744073709551615'), { - error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', - }) - ) - ), +export const zIntContractStorageNextTouch = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -10135,23 +10158,16 @@ export const zIntContractStorageReactivation12m = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - effective_bytes: z.optional( - z.coerce - .bigint() - .check( - z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), - z.maximum(BigInt('18446744073709551615'), { - error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', - }) - ) - ), - touch_block: z.optional( - z - .int() - .check( - z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), - z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) - ) + next_touch_block: z.optional( + z.union([ + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ), + z.null(), + ]) ), updated_date_time: z.optional( z @@ -10164,13 +10180,13 @@ export const zIntContractStorageReactivation12m = z.object({ }); /** - * Response for getting a single int_contract_storage_reactivation_12m record + * Response for getting a single int_contract_storage_next_touch record */ -export const zGetIntContractStorageReactivation12mResponse = z.object({ - item: z.optional(zIntContractStorageReactivation12m), +export const zGetIntContractStorageNextTouchResponse = z.object({ + item: z.optional(zIntContractStorageNextTouch), }); -export const zIntContractStorageReactivation18m = z.object({ +export const zIntContractStorageReactivation1m = z.object({ active_slots: z.optional( z.coerce .bigint() @@ -10219,13 +10235,178 @@ export const zIntContractStorageReactivation18m = z.object({ }); /** - * Response for getting a single int_contract_storage_reactivation_18m record + * Response for getting a single int_contract_storage_reactivation_1m record */ -export const zGetIntContractStorageReactivation18mResponse = z.object({ - item: z.optional(zIntContractStorageReactivation18m), +export const zGetIntContractStorageReactivation1mResponse = z.object({ + item: z.optional(zIntContractStorageReactivation1m), }); -export const zIntContractStorageReactivation24m = z.object({ +export const zIntContractStorageReactivation6m = z.object({ + active_slots: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), + z.maximum(BigInt('18446744073709551615'), { + error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', + }) + ) + ), + address: z.optional(z.string()), + block_number: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + effective_bytes: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), + z.maximum(BigInt('18446744073709551615'), { + error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', + }) + ) + ), + touch_block: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), +}); + +/** + * Response for getting a single int_contract_storage_reactivation_6m record + */ +export const zGetIntContractStorageReactivation6mResponse = z.object({ + item: z.optional(zIntContractStorageReactivation6m), +}); + +export const zIntContractStorageReactivation12m = z.object({ + active_slots: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), + z.maximum(BigInt('18446744073709551615'), { + error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', + }) + ) + ), + address: z.optional(z.string()), + block_number: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + effective_bytes: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), + z.maximum(BigInt('18446744073709551615'), { + error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', + }) + ) + ), + touch_block: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), +}); + +/** + * Response for getting a single int_contract_storage_reactivation_12m record + */ +export const zGetIntContractStorageReactivation12mResponse = z.object({ + item: z.optional(zIntContractStorageReactivation12m), +}); + +export const zIntContractStorageReactivation18m = z.object({ + active_slots: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), + z.maximum(BigInt('18446744073709551615'), { + error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', + }) + ) + ), + address: z.optional(z.string()), + block_number: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + effective_bytes: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('0'), { error: 'Invalid value: Expected uint64 to be >= 0' }), + z.maximum(BigInt('18446744073709551615'), { + error: 'Invalid value: Expected uint64 to be <= 18446744073709551615', + }) + ) + ), + touch_block: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), +}); + +/** + * Response for getting a single int_contract_storage_reactivation_18m record + */ +export const zGetIntContractStorageReactivation18mResponse = z.object({ + item: z.optional(zIntContractStorageReactivation18m), +}); + +export const zIntContractStorageReactivation24m = z.object({ active_slots: z.optional( z.coerce .bigint() @@ -11331,7 +11512,7 @@ export const zGetIntEngineNewPayloadResponse = z.object({ item: z.optional(zIntEngineNewPayload), }); -export const zIntEngineNewPayloadFastest = z.object({ +export const zIntEngineNewPayloadFastestExecutionByNodeClass = z.object({ block_hash: z.optional(z.string()), duration_ms: z.optional( z.coerce @@ -11390,10 +11571,10 @@ export const zIntEngineNewPayloadFastest = z.object({ }); /** - * Response for getting a single int_engine_new_payload_fastest record + * Response for getting a single int_engine_new_payload_fastest_execution_by_node_class record */ -export const zGetIntEngineNewPayloadFastestResponse = z.object({ - item: z.optional(zIntEngineNewPayloadFastest), +export const zGetIntEngineNewPayloadFastestExecutionByNodeClassResponse = z.object({ + item: z.optional(zIntEngineNewPayloadFastestExecutionByNodeClass), }); export const zIntExecutionBlockByDate = z.object({ @@ -11436,7 +11617,7 @@ export const zGetIntExecutionBlockByDateResponse = z.object({ item: z.optional(zIntExecutionBlockByDate), }); -export const zIntStorageSlotDiff = z.object({ +export const zIntStorageSelfdestructDiffs = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -11446,7 +11627,8 @@ export const zIntStorageSlotDiff = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - effective_bytes_from: z.optional( + from_value: z.optional(z.string()), + internal_index: z.optional( z .int() .check( @@ -11454,7 +11636,10 @@ export const zIntStorageSlotDiff = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - effective_bytes_to: z.optional( + slot: z.optional(z.string()), + to_value: z.optional(z.string()), + transaction_hash: z.optional(z.string()), + transaction_index: z.optional( z .int() .check( @@ -11462,7 +11647,6 @@ export const zIntStorageSlotDiff = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - slot_key: z.optional(z.string()), updated_date_time: z.optional( z .int() @@ -11474,13 +11658,13 @@ export const zIntStorageSlotDiff = z.object({ }); /** - * Response for getting a single int_storage_slot_diff record + * Response for getting a single int_storage_selfdestruct_diffs record */ -export const zGetIntStorageSlotDiffResponse = z.object({ - item: z.optional(zIntStorageSlotDiff), +export const zGetIntStorageSelfdestructDiffsResponse = z.object({ + item: z.optional(zIntStorageSelfdestructDiffs), }); -export const zIntStorageSlotDiffByAddressSlot = z.object({ +export const zIntStorageSlotDiff = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -11518,13 +11702,13 @@ export const zIntStorageSlotDiffByAddressSlot = z.object({ }); /** - * Response for getting a single int_storage_slot_diff_by_address_slot record + * Response for getting a single int_storage_slot_diff record */ -export const zGetIntStorageSlotDiffByAddressSlotResponse = z.object({ - item: z.optional(zIntStorageSlotDiffByAddressSlot), +export const zGetIntStorageSlotDiffResponse = z.object({ + item: z.optional(zIntStorageSlotDiff), }); -export const zIntStorageSlotExpiry1m = z.object({ +export const zIntStorageSlotDiffByAddressSlot = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -11534,7 +11718,7 @@ export const zIntStorageSlotExpiry1m = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - effective_bytes: z.optional( + effective_bytes_from: z.optional( z .int() .check( @@ -11542,8 +11726,7 @@ export const zIntStorageSlotExpiry1m = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), - slot_key: z.optional(z.string()), - touch_block: z.optional( + effective_bytes_to: z.optional( z .int() .check( @@ -11551,6 +11734,7 @@ export const zIntStorageSlotExpiry1m = z.object({ z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) ) ), + slot_key: z.optional(z.string()), updated_date_time: z.optional( z .int() @@ -11562,13 +11746,13 @@ export const zIntStorageSlotExpiry1m = z.object({ }); /** - * Response for getting a single int_storage_slot_expiry_1m record + * Response for getting a single int_storage_slot_diff_by_address_slot record */ -export const zGetIntStorageSlotExpiry1mResponse = z.object({ - item: z.optional(zIntStorageSlotExpiry1m), +export const zGetIntStorageSlotDiffByAddressSlotResponse = z.object({ + item: z.optional(zIntStorageSlotDiffByAddressSlot), }); -export const zIntStorageSlotExpiry6m = z.object({ +export const zIntStorageSlotExpiry1m = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -11606,13 +11790,13 @@ export const zIntStorageSlotExpiry6m = z.object({ }); /** - * Response for getting a single int_storage_slot_expiry_6m record + * Response for getting a single int_storage_slot_expiry_1m record */ -export const zGetIntStorageSlotExpiry6mResponse = z.object({ - item: z.optional(zIntStorageSlotExpiry6m), +export const zGetIntStorageSlotExpiry1mResponse = z.object({ + item: z.optional(zIntStorageSlotExpiry1m), }); -export const zIntStorageSlotExpiry12m = z.object({ +export const zIntStorageSlotExpiry6m = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -11650,13 +11834,13 @@ export const zIntStorageSlotExpiry12m = z.object({ }); /** - * Response for getting a single int_storage_slot_expiry_12m record + * Response for getting a single int_storage_slot_expiry_6m record */ -export const zGetIntStorageSlotExpiry12mResponse = z.object({ - item: z.optional(zIntStorageSlotExpiry12m), +export const zGetIntStorageSlotExpiry6mResponse = z.object({ + item: z.optional(zIntStorageSlotExpiry6m), }); -export const zIntStorageSlotExpiry18m = z.object({ +export const zIntStorageSlotExpiry12m = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -11694,13 +11878,13 @@ export const zIntStorageSlotExpiry18m = z.object({ }); /** - * Response for getting a single int_storage_slot_expiry_18m record + * Response for getting a single int_storage_slot_expiry_12m record */ -export const zGetIntStorageSlotExpiry18mResponse = z.object({ - item: z.optional(zIntStorageSlotExpiry18m), +export const zGetIntStorageSlotExpiry12mResponse = z.object({ + item: z.optional(zIntStorageSlotExpiry12m), }); -export const zIntStorageSlotExpiry24m = z.object({ +export const zIntStorageSlotExpiry18m = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -11738,52 +11922,96 @@ export const zIntStorageSlotExpiry24m = z.object({ }); /** - * Response for getting a single int_storage_slot_expiry_24m record - */ -export const zGetIntStorageSlotExpiry24mResponse = z.object({ - item: z.optional(zIntStorageSlotExpiry24m), -}); - -export const zIntStorageSlotNextTouch = z.object({ - address: z.optional(z.string()), - block_number: z.optional( - z - .int() - .check( - z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), - z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) - ) - ), - next_touch_block: z.optional( - z.union([ - z - .int() - .check( - z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), - z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) - ), - z.null(), - ]) - ), - slot_key: z.optional(z.string()), - updated_date_time: z.optional( - z - .int() - .check( - z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), - z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) - ) - ), -}); - -/** - * Response for getting a single int_storage_slot_next_touch record + * Response for getting a single int_storage_slot_expiry_18m record */ -export const zGetIntStorageSlotNextTouchResponse = z.object({ - item: z.optional(zIntStorageSlotNextTouch), +export const zGetIntStorageSlotExpiry18mResponse = z.object({ + item: z.optional(zIntStorageSlotExpiry18m), }); -export const zIntStorageSlotReactivation1m = z.object({ +export const zIntStorageSlotExpiry24m = z.object({ + address: z.optional(z.string()), + block_number: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + effective_bytes: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + slot_key: z.optional(z.string()), + touch_block: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), +}); + +/** + * Response for getting a single int_storage_slot_expiry_24m record + */ +export const zGetIntStorageSlotExpiry24mResponse = z.object({ + item: z.optional(zIntStorageSlotExpiry24m), +}); + +export const zIntStorageSlotNextTouch = z.object({ + address: z.optional(z.string()), + block_number: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + next_touch_block: z.optional( + z.union([ + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ), + z.null(), + ]) + ), + slot_key: z.optional(z.string()), + updated_date_time: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), +}); + +/** + * Response for getting a single int_storage_slot_next_touch record + */ +export const zGetIntStorageSlotNextTouchResponse = z.object({ + item: z.optional(zIntStorageSlotNextTouch), +}); + +export const zIntStorageSlotReactivation1m = z.object({ address: z.optional(z.string()), block_number: z.optional( z @@ -13578,6 +13806,14 @@ export const zListFctNodeActiveLast24hResponse = z.object({ next_page_token: z.optional(z.string()), }); +/** + * Response for listing fct_node_cpu_utilization records + */ +export const zListFctNodeCpuUtilizationResponse = z.object({ + fct_node_cpu_utilization: z.optional(z.array(zFctNodeCpuUtilization)), + next_page_token: z.optional(z.string()), +}); + /** * Response for listing fct_opcode_gas_by_opcode_daily records */ @@ -13890,6 +14126,22 @@ export const zListIntBlockProposerCanonicalResponse = z.object({ next_page_token: z.optional(z.string()), }); +/** + * Response for listing int_contract_creation records + */ +export const zListIntContractCreationResponse = z.object({ + int_contract_creation: z.optional(z.array(zIntContractCreation)), + next_page_token: z.optional(z.string()), +}); + +/** + * Response for listing int_contract_selfdestruct records + */ +export const zListIntContractSelfdestructResponse = z.object({ + int_contract_selfdestruct: z.optional(z.array(zIntContractSelfdestruct)), + next_page_token: z.optional(z.string()), +}); + /** * Response for listing int_contract_storage_expiry_1m records */ @@ -14051,10 +14303,12 @@ export const zListIntEngineGetBlobsResponse = z.object({ }); /** - * Response for listing int_engine_new_payload_fastest records + * Response for listing int_engine_new_payload_fastest_execution_by_node_class records */ -export const zListIntEngineNewPayloadFastestResponse = z.object({ - int_engine_new_payload_fastest: z.optional(z.array(zIntEngineNewPayloadFastest)), +export const zListIntEngineNewPayloadFastestExecutionByNodeClassResponse = z.object({ + int_engine_new_payload_fastest_execution_by_node_class: z.optional( + z.array(zIntEngineNewPayloadFastestExecutionByNodeClass) + ), next_page_token: z.optional(z.string()), }); @@ -14074,6 +14328,14 @@ export const zListIntExecutionBlockByDateResponse = z.object({ next_page_token: z.optional(z.string()), }); +/** + * Response for listing int_storage_selfdestruct_diffs records + */ +export const zListIntStorageSelfdestructDiffsResponse = z.object({ + int_storage_selfdestruct_diffs: z.optional(z.array(zIntStorageSelfdestructDiffs)), + next_page_token: z.optional(z.string()), +}); + /** * Response for listing int_storage_slot_diff_by_address_slot records */ @@ -68705,29 +68967,575 @@ export const zFctNodeActiveLast24hServiceGetData = z.object({ */ export const zFctNodeActiveLast24hServiceGetResponse = zGetFctNodeActiveLast24hResponse; -export const zFctOpcodeGasByOpcodeDailyServiceListData = z.object({ +export const zFctNodeCpuUtilizationServiceListData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.optional( z.object({ - day_start_date_eq: z.optional(z.string()), - day_start_date_ne: z.optional(z.string()), - day_start_date_contains: z.optional(z.string()), - day_start_date_starts_with: z.optional(z.string()), - day_start_date_ends_with: z.optional(z.string()), - day_start_date_like: z.optional(z.string()), - day_start_date_not_like: z.optional(z.string()), - day_start_date_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), - day_start_date_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), - opcode_eq: z.optional(z.string()), - opcode_ne: z.optional(z.string()), - opcode_contains: z.optional(z.string()), - opcode_starts_with: z.optional(z.string()), - opcode_ends_with: z.optional(z.string()), - opcode_like: z.optional(z.string()), - opcode_not_like: z.optional(z.string()), - opcode_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), - opcode_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + wallclock_slot_start_date_time_eq: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + wallclock_slot_start_date_time_ne: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + wallclock_slot_start_date_time_lt: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + wallclock_slot_start_date_time_lte: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + wallclock_slot_start_date_time_gt: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + wallclock_slot_start_date_time_gte: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + wallclock_slot_start_date_time_between_min: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + wallclock_slot_start_date_time_between_max_value: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + wallclock_slot_start_date_time_in_values: z.optional(z.string().check(z.regex(/^-?\d+(,-?\d+)*$/))), + wallclock_slot_start_date_time_not_in_values: z.optional(z.string().check(z.regex(/^-?\d+(,-?\d+)*$/))), + meta_client_name_eq: z.optional(z.string()), + meta_client_name_ne: z.optional(z.string()), + meta_client_name_contains: z.optional(z.string()), + meta_client_name_starts_with: z.optional(z.string()), + meta_client_name_ends_with: z.optional(z.string()), + meta_client_name_like: z.optional(z.string()), + meta_client_name_not_like: z.optional(z.string()), + meta_client_name_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + meta_client_name_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + client_type_eq: z.optional(z.string()), + client_type_ne: z.optional(z.string()), + client_type_contains: z.optional(z.string()), + client_type_starts_with: z.optional(z.string()), + client_type_ends_with: z.optional(z.string()), + client_type_like: z.optional(z.string()), + client_type_not_like: z.optional(z.string()), + client_type_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + client_type_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + pid_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + pid_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + pid_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + pid_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + pid_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + pid_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + pid_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + pid_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + pid_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + pid_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + window_start_eq: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start_ne: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start_lt: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start_lte: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start_gt: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start_gte: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start_between_min: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start_between_max_value: z.optional( + z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ) + ), + window_start_in_values: z.optional(z.string().check(z.regex(/^-?\d+(,-?\d+)*$/))), + window_start_not_in_values: z.optional(z.string().check(z.regex(/^-?\d+(,-?\d+)*$/))), + updated_date_time_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + updated_date_time_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + wallclock_slot_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + wallclock_slot_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + wallclock_slot_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + meta_network_name_eq: z.optional(z.string()), + meta_network_name_ne: z.optional(z.string()), + meta_network_name_contains: z.optional(z.string()), + meta_network_name_starts_with: z.optional(z.string()), + meta_network_name_ends_with: z.optional(z.string()), + meta_network_name_like: z.optional(z.string()), + meta_network_name_not_like: z.optional(z.string()), + meta_network_name_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + meta_network_name_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + system_cores_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + system_cores_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + system_cores_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + mean_core_pct_value: z.optional(z.number()), + min_core_pct_value: z.optional(z.number()), + max_core_pct_value: z.optional(z.number()), + max_single_core_pct_value: z.optional(z.number()), + node_class_eq: z.optional(z.string()), + node_class_ne: z.optional(z.string()), + node_class_contains: z.optional(z.string()), + node_class_starts_with: z.optional(z.string()), + node_class_ends_with: z.optional(z.string()), + node_class_like: z.optional(z.string()), + node_class_not_like: z.optional(z.string()), + node_class_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + node_class_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + page_size: z.optional( + z + .int() + .check( + z.minimum(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }), + z.maximum(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + ) + ), + page_token: z.optional(z.string()), + order_by: z.optional(z.string()), + }) + ), +}); + +/** + * OK + */ +export const zFctNodeCpuUtilizationServiceListResponse = zListFctNodeCpuUtilizationResponse; + +export const zFctNodeCpuUtilizationServiceGetData = z.object({ + body: z.optional(z.never()), + path: z.object({ + wallclock_slot_start_date_time: z.coerce + .bigint() + .check( + z.minimum(BigInt('-9223372036854775808'), { + error: 'Invalid value: Expected int64 to be >= -9223372036854775808', + }), + z.maximum(BigInt('9223372036854775807'), { + error: 'Invalid value: Expected int64 to be <= 9223372036854775807', + }) + ), + }), + query: z.optional(z.never()), +}); + +/** + * OK + */ +export const zFctNodeCpuUtilizationServiceGetResponse = zGetFctNodeCpuUtilizationResponse; + +export const zFctOpcodeGasByOpcodeDailyServiceListData = z.object({ + body: z.optional(z.never()), + path: z.optional(z.never()), + query: z.optional( + z.object({ + day_start_date_eq: z.optional(z.string()), + day_start_date_ne: z.optional(z.string()), + day_start_date_contains: z.optional(z.string()), + day_start_date_starts_with: z.optional(z.string()), + day_start_date_ends_with: z.optional(z.string()), + day_start_date_like: z.optional(z.string()), + day_start_date_not_like: z.optional(z.string()), + day_start_date_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + day_start_date_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + opcode_eq: z.optional(z.string()), + opcode_ne: z.optional(z.string()), + opcode_contains: z.optional(z.string()), + opcode_starts_with: z.optional(z.string()), + opcode_ends_with: z.optional(z.string()), + opcode_like: z.optional(z.string()), + opcode_not_like: z.optional(z.string()), + opcode_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + opcode_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), updated_date_time_eq: z.optional( z .int() @@ -86183,6 +86991,778 @@ export const zIntBlockProposerCanonicalServiceGetData = z.object({ */ export const zIntBlockProposerCanonicalServiceGetResponse = zGetIntBlockProposerCanonicalResponse; +export const zIntContractCreationServiceListData = z.object({ + body: z.optional(z.never()), + path: z.optional(z.never()), + query: z.optional( + z.object({ + block_number_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + block_number_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + contract_address_eq: z.optional(z.string()), + contract_address_ne: z.optional(z.string()), + contract_address_contains: z.optional(z.string()), + contract_address_starts_with: z.optional(z.string()), + contract_address_ends_with: z.optional(z.string()), + contract_address_like: z.optional(z.string()), + contract_address_not_like: z.optional(z.string()), + contract_address_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + contract_address_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + transaction_hash_eq: z.optional(z.string()), + transaction_hash_ne: z.optional(z.string()), + transaction_hash_contains: z.optional(z.string()), + transaction_hash_starts_with: z.optional(z.string()), + transaction_hash_ends_with: z.optional(z.string()), + transaction_hash_like: z.optional(z.string()), + transaction_hash_not_like: z.optional(z.string()), + transaction_hash_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + transaction_hash_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + updated_date_time_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + updated_date_time_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + transaction_index_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + transaction_index_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + internal_index_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + internal_index_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + deployer_eq: z.optional(z.string()), + deployer_ne: z.optional(z.string()), + deployer_contains: z.optional(z.string()), + deployer_starts_with: z.optional(z.string()), + deployer_ends_with: z.optional(z.string()), + deployer_like: z.optional(z.string()), + deployer_not_like: z.optional(z.string()), + deployer_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + deployer_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + factory_eq: z.optional(z.string()), + factory_ne: z.optional(z.string()), + factory_contains: z.optional(z.string()), + factory_starts_with: z.optional(z.string()), + factory_ends_with: z.optional(z.string()), + factory_like: z.optional(z.string()), + factory_not_like: z.optional(z.string()), + factory_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + factory_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + init_code_hash_eq: z.optional(z.string()), + init_code_hash_ne: z.optional(z.string()), + init_code_hash_contains: z.optional(z.string()), + init_code_hash_starts_with: z.optional(z.string()), + init_code_hash_ends_with: z.optional(z.string()), + init_code_hash_like: z.optional(z.string()), + init_code_hash_not_like: z.optional(z.string()), + init_code_hash_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + init_code_hash_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + page_size: z.optional( + z + .int() + .check( + z.minimum(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }), + z.maximum(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + ) + ), + page_token: z.optional(z.string()), + order_by: z.optional(z.string()), + }) + ), +}); + +/** + * OK + */ +export const zIntContractCreationServiceListResponse = zListIntContractCreationResponse; + +export const zIntContractCreationServiceGetData = z.object({ + body: z.optional(z.never()), + path: z.object({ + block_number: z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ), + }), + query: z.optional(z.never()), +}); + +/** + * OK + */ +export const zIntContractCreationServiceGetResponse = zGetIntContractCreationResponse; + +export const zIntContractSelfdestructServiceListData = z.object({ + body: z.optional(z.never()), + path: z.optional(z.never()), + query: z.optional( + z.object({ + block_number_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + block_number_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + transaction_index_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + transaction_index_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + internal_index_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + internal_index_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + address_eq: z.optional(z.string()), + address_ne: z.optional(z.string()), + address_contains: z.optional(z.string()), + address_starts_with: z.optional(z.string()), + address_ends_with: z.optional(z.string()), + address_like: z.optional(z.string()), + address_not_like: z.optional(z.string()), + address_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + address_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + updated_date_time_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + updated_date_time_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + transaction_hash_eq: z.optional(z.string()), + transaction_hash_ne: z.optional(z.string()), + transaction_hash_contains: z.optional(z.string()), + transaction_hash_starts_with: z.optional(z.string()), + transaction_hash_ends_with: z.optional(z.string()), + transaction_hash_like: z.optional(z.string()), + transaction_hash_not_like: z.optional(z.string()), + transaction_hash_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + transaction_hash_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + beneficiary_eq: z.optional(z.string()), + beneficiary_ne: z.optional(z.string()), + beneficiary_contains: z.optional(z.string()), + beneficiary_starts_with: z.optional(z.string()), + beneficiary_ends_with: z.optional(z.string()), + beneficiary_like: z.optional(z.string()), + beneficiary_not_like: z.optional(z.string()), + beneficiary_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + beneficiary_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + value_transferred_eq: z.optional(z.string()), + value_transferred_ne: z.optional(z.string()), + value_transferred_contains: z.optional(z.string()), + value_transferred_starts_with: z.optional(z.string()), + value_transferred_ends_with: z.optional(z.string()), + value_transferred_like: z.optional(z.string()), + value_transferred_not_like: z.optional(z.string()), + value_transferred_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + value_transferred_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + ephemeral_eq: z.optional(z.boolean()), + ephemeral_ne: z.optional(z.boolean()), + storage_cleared_eq: z.optional(z.boolean()), + storage_cleared_ne: z.optional(z.boolean()), + creation_block_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + creation_block_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + creation_block_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + creation_block_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + creation_block_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + creation_block_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + creation_block_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + creation_block_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + creation_block_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + creation_block_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + creation_transaction_hash_eq: z.optional(z.string()), + creation_transaction_hash_ne: z.optional(z.string()), + creation_transaction_hash_contains: z.optional(z.string()), + creation_transaction_hash_starts_with: z.optional(z.string()), + creation_transaction_hash_ends_with: z.optional(z.string()), + creation_transaction_hash_like: z.optional(z.string()), + creation_transaction_hash_not_like: z.optional(z.string()), + creation_transaction_hash_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + creation_transaction_hash_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + page_size: z.optional( + z + .int() + .check( + z.minimum(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }), + z.maximum(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + ) + ), + page_token: z.optional(z.string()), + order_by: z.optional(z.string()), + }) + ), +}); + +/** + * OK + */ +export const zIntContractSelfdestructServiceListResponse = zListIntContractSelfdestructResponse; + +export const zIntContractSelfdestructServiceGetData = z.object({ + body: z.optional(z.never()), + path: z.object({ + block_number: z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ), + }), + query: z.optional(z.never()), +}); + +/** + * OK + */ +export const zIntContractSelfdestructServiceGetResponse = zGetIntContractSelfdestructResponse; + export const zIntContractStorageExpiry1mServiceListData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), @@ -98621,7 +100201,7 @@ export const zIntEngineNewPayloadServiceGetData = z.object({ */ export const zIntEngineNewPayloadServiceGetResponse = zGetIntEngineNewPayloadResponse; -export const zIntEngineNewPayloadFastestServiceListData = z.object({ +export const zIntEngineNewPayloadFastestExecutionByNodeClassServiceListData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.optional( @@ -99100,9 +100680,10 @@ export const zIntEngineNewPayloadFastestServiceListData = z.object({ /** * OK */ -export const zIntEngineNewPayloadFastestServiceListResponse = zListIntEngineNewPayloadFastestResponse; +export const zIntEngineNewPayloadFastestExecutionByNodeClassServiceListResponse = + zListIntEngineNewPayloadFastestExecutionByNodeClassResponse; -export const zIntEngineNewPayloadFastestServiceGetData = z.object({ +export const zIntEngineNewPayloadFastestExecutionByNodeClassServiceGetData = z.object({ body: z.optional(z.never()), path: z.object({ slot_start_date_time: z @@ -99118,7 +100699,8 @@ export const zIntEngineNewPayloadFastestServiceGetData = z.object({ /** * OK */ -export const zIntEngineNewPayloadFastestServiceGetResponse = zGetIntEngineNewPayloadFastestResponse; +export const zIntEngineNewPayloadFastestExecutionByNodeClassServiceGetResponse = + zGetIntEngineNewPayloadFastestExecutionByNodeClassResponse; export const zIntExecutionBlockByDateServiceListData = z.object({ body: z.optional(z.never()), @@ -99412,6 +100994,357 @@ export const zIntExecutionBlockByDateServiceGetData = z.object({ */ export const zIntExecutionBlockByDateServiceGetResponse = zGetIntExecutionBlockByDateResponse; +export const zIntStorageSelfdestructDiffsServiceListData = z.object({ + body: z.optional(z.never()), + path: z.optional(z.never()), + query: z.optional( + z.object({ + block_number_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + block_number_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + block_number_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + transaction_hash_eq: z.optional(z.string()), + transaction_hash_ne: z.optional(z.string()), + transaction_hash_contains: z.optional(z.string()), + transaction_hash_starts_with: z.optional(z.string()), + transaction_hash_ends_with: z.optional(z.string()), + transaction_hash_like: z.optional(z.string()), + transaction_hash_not_like: z.optional(z.string()), + transaction_hash_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + transaction_hash_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + internal_index_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + internal_index_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + internal_index_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + slot_eq: z.optional(z.string()), + slot_ne: z.optional(z.string()), + slot_contains: z.optional(z.string()), + slot_starts_with: z.optional(z.string()), + slot_ends_with: z.optional(z.string()), + slot_like: z.optional(z.string()), + slot_not_like: z.optional(z.string()), + slot_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + slot_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + updated_date_time_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + updated_date_time_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + updated_date_time_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + transaction_index_eq: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_ne: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_lt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_lte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_gt: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_gte: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_between_min: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_between_max_value: z.optional( + z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ) + ), + transaction_index_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + transaction_index_not_in_values: z.optional(z.string().check(z.regex(/^\d+(,\d+)*$/))), + address_eq: z.optional(z.string()), + address_ne: z.optional(z.string()), + address_contains: z.optional(z.string()), + address_starts_with: z.optional(z.string()), + address_ends_with: z.optional(z.string()), + address_like: z.optional(z.string()), + address_not_like: z.optional(z.string()), + address_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + address_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + from_value_eq: z.optional(z.string()), + from_value_ne: z.optional(z.string()), + from_value_contains: z.optional(z.string()), + from_value_starts_with: z.optional(z.string()), + from_value_ends_with: z.optional(z.string()), + from_value_like: z.optional(z.string()), + from_value_not_like: z.optional(z.string()), + from_value_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + from_value_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + to_value_eq: z.optional(z.string()), + to_value_ne: z.optional(z.string()), + to_value_contains: z.optional(z.string()), + to_value_starts_with: z.optional(z.string()), + to_value_ends_with: z.optional(z.string()), + to_value_like: z.optional(z.string()), + to_value_not_like: z.optional(z.string()), + to_value_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + to_value_not_in_values: z.optional(z.string().check(z.regex(/^[^,]+(,[^,]+)*$/))), + page_size: z.optional( + z + .int() + .check( + z.minimum(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }), + z.maximum(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + ) + ), + page_token: z.optional(z.string()), + order_by: z.optional(z.string()), + }) + ), +}); + +/** + * OK + */ +export const zIntStorageSelfdestructDiffsServiceListResponse = zListIntStorageSelfdestructDiffsResponse; + +export const zIntStorageSelfdestructDiffsServiceGetData = z.object({ + body: z.optional(z.never()), + path: z.object({ + block_number: z + .int() + .check( + z.minimum(0, { error: 'Invalid value: Expected uint32 to be >= 0' }), + z.maximum(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + ), + }), + query: z.optional(z.never()), +}); + +/** + * OK + */ +export const zIntStorageSelfdestructDiffsServiceGetResponse = zGetIntStorageSelfdestructDiffsResponse; + export const zIntStorageSlotDiffServiceListData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), diff --git a/src/pages/ethereum/slots/DetailPage.tsx b/src/pages/ethereum/slots/DetailPage.tsx index 76c5702d8..b53ae8913 100644 --- a/src/pages/ethereum/slots/DetailPage.tsx +++ b/src/pages/ethereum/slots/DetailPage.tsx @@ -41,6 +41,7 @@ import { SlotDetailSkeleton } from './components/SlotDetailSkeleton'; import { EngineTimingsCard } from './components/EngineTimingsCard'; import { SlotProgressTimeline } from './components/SlotProgressTimeline'; import { useSlotEngineTimings } from './hooks/useSlotEngineTimings'; +import { NodeResourcesPanel } from './components/NodeResources'; /** * Detail page for a specific slot. @@ -143,6 +144,7 @@ export function DetailPage(): JSX.Element { { id: 'blobs' }, { id: 'execution' }, { id: 'mev' }, + { id: 'resources' }, ]); // Validate slot number @@ -393,6 +395,7 @@ export function DetailPage(): JSX.Element { Blobs Execution MEV + Node Resources @@ -1120,6 +1123,14 @@ export function DetailPage(): JSX.Element { )} + + {/* Node Resources Tab */} + + + diff --git a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx new file mode 100644 index 000000000..ec6a5d9be --- /dev/null +++ b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx @@ -0,0 +1,317 @@ +import { type JSX, useMemo } from 'react'; +import { PopoutCard } from '@/components/Layout/PopoutCard'; +import { MultiLineChart } from '@/components/Charts/MultiLine'; +import type { SeriesData, MarkLineConfig } from '@/components/Charts/MultiLine/MultiLine.types'; +import { getDataVizColors } from '@/utils'; +import { ClientLogo } from '@/components/Ethereum/ClientLogo'; +import type { FctNodeCpuUtilization } from '@/api/types.gen'; +import type { CpuMetric } from './NodeResourcesPanel'; + +const CL_CLIENTS = new Set(['lighthouse', 'lodestar', 'nimbus', 'prysm', 'teku', 'grandine']); +const EL_CLIENTS = new Set(['besu', 'erigon', 'geth', 'nethermind', 'reth']); + +function getClientLayer(clientType: string): 'CL' | 'EL' | null { + const lower = clientType.toLowerCase(); + if (CL_CLIENTS.has(lower)) return 'CL'; + if (EL_CLIENTS.has(lower)) return 'EL'; + return null; +} + +/** Convert API microsecond timestamp to seconds */ +function usToSeconds(us: number): number { + return us / 1_000_000; +} + +/** Get the normalized metric value (0-100% of total system) from a data point */ +function getMetricValue(d: FctNodeCpuUtilization, metric: CpuMetric): number { + const cores = d.system_cores ?? 1; + const divisor = cores > 0 ? cores : 1; + switch (metric) { + case 'min': + return (d.min_core_pct ?? 0) / divisor; + case 'max': + return (d.max_core_pct ?? 0) / divisor; + case 'mean': + default: + return (d.mean_core_pct ?? 0) / divisor; + } +} + +const METRIC_LABELS: Record = { + mean: 'Mean', + min: 'Min', + max: 'Max', +}; + +interface BlockArrival { + seen_slot_start_diff: number; + node_id: string; +} + +interface CpuUtilizationChartProps { + data: FctNodeCpuUtilization[]; + selectedNode: string | null; + blockPropagationData: BlockArrival[]; + metric: CpuMetric; +} + +export function CpuUtilizationChart({ + data, + selectedNode, + blockPropagationData, + metric, +}: CpuUtilizationChartProps): JSX.Element { + const { CHART_CATEGORICAL_COLORS } = getDataVizColors(); + + const { series, markLines, clClient, elClient } = useMemo(() => { + if (data.length === 0) { + return { series: [] as SeriesData[], markLines: [] as MarkLineConfig[], clClient: '', elClient: '' }; + } + + // Derive slot start time from data (microseconds) + const slotStartUs = Math.min(...data.map(d => d.wallclock_slot_start_date_time ?? 0).filter(v => v > 0)); + + const chartSeries: SeriesData[] = []; + let resolvedClClient = ''; + let resolvedElClient = ''; + + // Bucket size for time aggregation (seconds) + const BUCKET_SIZE = 0.25; + const toBucket = (offsetSec: number): number => Math.round(offsetSec / BUCKET_SIZE) * BUCKET_SIZE; + + const buildLine = ( + items: FctNodeCpuUtilization[], + label: string, + color: string, + getValue: CpuMetric | ((d: FctNodeCpuUtilization) => number), + opts?: { + lineWidth?: number; + showArea?: boolean; + areaOpacity?: number; + lineStyle?: 'solid' | 'dashed' | 'dotted'; + } + ): void => { + const extractValue = + typeof getValue === 'function' ? getValue : (d: FctNodeCpuUtilization) => getMetricValue(d, getValue); + + const byBucket = new Map(); + items.forEach(d => { + const offset = usToSeconds((d.window_start ?? 0) - slotStartUs); + const bucket = toBucket(offset); + if (bucket < 0 || bucket > 12) return; + if (!byBucket.has(bucket)) byBucket.set(bucket, []); + byBucket.get(bucket)!.push(extractValue(d)); + }); + + const points = Array.from(byBucket.entries()) + .sort(([a], [b]) => a - b) + .map(([offset, values]) => [offset, values.reduce((s, v) => s + v, 0) / values.length] as [number, number]); + + if (points.length > 0) { + chartSeries.push({ + name: label, + data: points, + color, + lineWidth: opts?.lineWidth ?? 2, + showArea: opts?.showArea ?? true, + areaOpacity: opts?.areaOpacity ?? 0.08, + lineStyle: opts?.lineStyle, + }); + } + }; + + if (selectedNode) { + const nodeData = data.filter(d => d.meta_client_name === selectedNode); + const clData = nodeData.filter(d => getClientLayer(d.client_type ?? '') === 'CL'); + const elData = nodeData.filter(d => getClientLayer(d.client_type ?? '') === 'EL'); + + resolvedClClient = clData[0]?.client_type ?? ''; + resolvedElClient = elData[0]?.client_type ?? ''; + + const clLabel = resolvedClClient || 'CL'; + const elLabel = resolvedElClient || 'EL'; + const clColor = CHART_CATEGORICAL_COLORS[0]; + const elColor = CHART_CATEGORICAL_COLORS[1]; + + const coreExtract = (d: FctNodeCpuUtilization) => Math.min(d.max_core_pct ?? 0, 100); + + // CL system utilization: mean (solid), min (dotted), max (dashed) + buildLine(clData, `${clLabel} sys mean`, clColor, 'mean', { lineWidth: 2, showArea: true, areaOpacity: 0.06 }); + buildLine(clData, `${clLabel} sys min`, clColor, 'min', { + lineWidth: 1.5, + showArea: false, + lineStyle: 'dotted', + }); + buildLine(clData, `${clLabel} sys max`, clColor, 'max', { + lineWidth: 1.5, + showArea: false, + lineStyle: 'dashed', + }); + + // EL system utilization: mean (solid), min (dotted), max (dashed) + buildLine(elData, `${elLabel} sys mean`, elColor, 'mean', { lineWidth: 2, showArea: true, areaOpacity: 0.06 }); + buildLine(elData, `${elLabel} sys min`, elColor, 'min', { + lineWidth: 1.5, + showArea: false, + lineStyle: 'dotted', + }); + buildLine(elData, `${elLabel} sys max`, elColor, 'max', { + lineWidth: 1.5, + showArea: false, + lineStyle: 'dashed', + }); + + // Hottest single core per client (raw, not divided by system_cores) + const singleCoreColor = CHART_CATEGORICAL_COLORS[2] ?? '#e5a00d'; + buildLine(clData, `${clLabel} hottest core`, singleCoreColor, coreExtract, { + lineWidth: 1.5, + showArea: false, + lineStyle: 'dashed', + }); + buildLine(elData, `${elLabel} hottest core`, singleCoreColor, coreExtract, { + lineWidth: 1.5, + showArea: false, + lineStyle: 'dotted', + }); + } else { + const clData = data.filter(d => getClientLayer(d.client_type ?? '') === 'CL'); + const elData = data.filter(d => getClientLayer(d.client_type ?? '') === 'EL'); + + buildLine(clData, 'Consensus Layer', CHART_CATEGORICAL_COLORS[0], metric); + buildLine(elData, 'Execution Layer', CHART_CATEGORICAL_COLORS[1], metric); + } + + // Block arrival markLines + const chartMarkLines: MarkLineConfig[] = []; + + if (blockPropagationData.length > 0) { + if (selectedNode) { + const shortNodeName = selectedNode.split('/').pop() ?? selectedNode; + const nodeArrival = blockPropagationData.find( + p => + p.node_id === shortNodeName || + p.node_id === selectedNode || + shortNodeName.includes(p.node_id) || + p.node_id.includes(shortNodeName) + ); + if (nodeArrival) { + chartMarkLines.push({ + xValue: nodeArrival.seen_slot_start_diff / 1000, + label: 'Block Arrival', + color: 'var(--color-warning)', + lineStyle: 'dashed', + lineWidth: 1, + }); + } else { + const arrivalTimes = blockPropagationData.map(p => p.seen_slot_start_diff).sort((a, b) => a - b); + const p50Index = Math.floor(arrivalTimes.length * 0.5); + chartMarkLines.push({ + xValue: arrivalTimes[p50Index] / 1000, + label: 'Block p50', + color: 'var(--color-warning)', + lineStyle: 'dotted', + lineWidth: 1, + }); + } + } else { + const arrivalTimes = blockPropagationData.map(p => p.seen_slot_start_diff).sort((a, b) => a - b); + if (arrivalTimes.length > 0) { + const p50Index = Math.floor(arrivalTimes.length * 0.5); + chartMarkLines.push({ + xValue: arrivalTimes[p50Index] / 1000, + label: 'Block p50', + color: 'var(--color-warning)', + lineStyle: 'dashed', + lineWidth: 1, + }); + } + } + } + + return { series: chartSeries, markLines: chartMarkLines, clClient: resolvedClClient, elClient: resolvedElClient }; + }, [data, selectedNode, blockPropagationData, metric, CHART_CATEGORICAL_COLORS]); + + const nodeCount = new Set(data.map(d => d.meta_client_name)).size; + const shortNodeName = selectedNode?.split('/').pop() ?? ''; + + const subtitle = selectedNode + ? `${shortNodeName} · sys% = total system, hottest core = single core peak` + : `${METRIC_LABELS[metric]} across ${nodeCount} nodes · % of total system`; + + const headerActions = + selectedNode && (clClient || elClient) ? ( +
+ {clClient && } + {elClient && } +
+ ) : undefined; + + if (data.length === 0) { + return ( + + {({ inModal }) => ( +
+
+

No CPU utilization data available for this slot

+
+
+ )} +
+ ); + } + + return ( + + {({ inModal }) => ( + `${v}s`, + }} + yAxis={{ + name: 'CPU %', + min: 0, + formatter: (v: number) => `${v.toFixed(1)}%`, + }} + height={inModal ? 500 : 350} + showLegend + legendPosition="bottom" + markLines={markLines} + syncGroup="slot-time" + valueDecimals={1} + tooltipFormatter={(params: unknown) => { + const items = Array.isArray(params) ? params : [params]; + if (items.length === 0) return ''; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const first = items[0] as any; + const xVal = Array.isArray(first.value) ? first.value[0] : first.axisValue; + const timeStr = typeof xVal === 'number' ? `${xVal.toFixed(3)}s` : `${xVal}s`; + + let html = `
`; + html += `
${timeStr}
`; + + for (const item of items) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const p = item as any; + const val = Array.isArray(p.value) ? p.value[1] : p.value; + if (val == null) continue; + html += `
`; + html += `${p.marker}`; + html += `${p.seriesName}`; + html += `${Number(val).toFixed(1)}%`; + html += `
`; + } + + html += `
`; + return html; + }} + /> + )} +
+ ); +} diff --git a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx new file mode 100644 index 000000000..95311373d --- /dev/null +++ b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx @@ -0,0 +1,210 @@ +import { type JSX, useState, useMemo, useCallback } from 'react'; +import { useSearch, useNavigate } from '@tanstack/react-router'; +import { InformationCircleIcon } from '@heroicons/react/24/outline'; +import { Card } from '@/components/Layout/Card'; +import { Checkbox } from '@/components/Forms/Checkbox'; +import { SelectMenu } from '@/components/Forms/SelectMenu'; +import { ReferenceNodesInfoDialog } from '@/pages/ethereum/execution/timings/components/ReferenceNodesInfoDialog'; +import { extractClusterFromNodeName } from '@/constants/eip7870'; +import { useSlotNodeResources } from '../../hooks/useSlotNodeResources'; +import { NodeSelector, type NodeClientInfo } from './NodeSelector'; +import { CpuUtilizationChart } from './CpuUtilizationChart'; + +export type CpuMetric = 'mean' | 'min' | 'max'; + +const CL_CLIENTS = new Set(['lighthouse', 'lodestar', 'nimbus', 'prysm', 'teku', 'grandine']); +const EL_CLIENTS = new Set(['besu', 'erigon', 'geth', 'nethermind', 'reth']); + +interface BlockArrival { + seen_slot_start_diff: number; + node_id: string; +} + +interface NodeResourcesPanelProps { + slot: number; + blockPropagationData: BlockArrival[]; +} + +const METRIC_OPTIONS = [ + { value: 'mean' as CpuMetric, label: 'Mean' }, + { value: 'min' as CpuMetric, label: 'Min' }, + { value: 'max' as CpuMetric, label: 'Max' }, +]; + +export function NodeResourcesPanel({ slot, blockPropagationData }: NodeResourcesPanelProps): JSX.Element { + const { data, isLoading, error } = useSlotNodeResources(slot); + const search = useSearch({ from: '/ethereum/slots/$slot' }); + const navigate = useNavigate(); + const [showRefNodeInfo, setShowRefNodeInfo] = useState(false); + + // URL-backed state + const referenceNodesOnly = search.refNodes ?? false; + const selectedNode = search.node ?? null; + const metric: CpuMetric = search.metric ?? 'mean'; + + const setReferenceNodesOnly = useCallback( + (value: boolean) => { + navigate({ + to: '/ethereum/slots/$slot', + params: { slot: String(slot) }, + search: prev => ({ ...prev, refNodes: value || undefined }), + replace: true, + }); + }, + [navigate, slot] + ); + + const setSelectedNode = useCallback( + (value: string | null) => { + navigate({ + to: '/ethereum/slots/$slot', + params: { slot: String(slot) }, + search: prev => ({ ...prev, node: value ?? undefined }), + replace: true, + }); + }, + [navigate, slot] + ); + + const setMetric = useCallback( + (value: CpuMetric) => { + navigate({ + to: '/ethereum/slots/$slot', + params: { slot: String(slot) }, + search: prev => ({ ...prev, metric: value === 'mean' ? undefined : value }), + replace: true, + }); + }, + [navigate, slot] + ); + + // Filter data based on reference nodes toggle + const filteredData = useMemo(() => { + if (!data) return []; + if (!referenceNodesOnly) return data; + return data.filter( + d => d.node_class === 'eip7870' || extractClusterFromNodeName(d.meta_client_name ?? '') !== null + ); + }, [data, referenceNodesOnly]); + + // Get unique node names from filtered data + const nodeNames = useMemo(() => { + const names = new Set(filteredData.map(d => d.meta_client_name).filter(Boolean) as string[]); + return Array.from(names).sort(); + }, [filteredData]); + + // Build node → {cl, el} client info map from the data + const nodeClientInfo = useMemo(() => { + const info = new Map(); + for (const d of filteredData) { + const name = d.meta_client_name; + const clientType = d.client_type?.toLowerCase() ?? ''; + if (!name) continue; + + const existing = info.get(name) ?? { cl: '', el: '' }; + if (CL_CLIENTS.has(clientType) && !existing.cl) { + existing.cl = clientType; + } else if (EL_CLIENTS.has(clientType) && !existing.el) { + existing.el = clientType; + } + info.set(name, existing); + } + return info; + }, [filteredData]); + + // Reset selected node if it's no longer in the filtered list + const effectiveSelectedNode = selectedNode && nodeNames.includes(selectedNode) ? selectedNode : null; + + if (isLoading) { + return ( + +
+

Node Resources

+

CPU utilization from observoor eBPF agent

+
+
+
+
+
+ + ); + } + + if (error) { + return ( + +
+

Failed to load node resource data: {error.message}

+
+
+ ); + } + + if (!data || data.length === 0) { + return ( + +
+

No node resource data available for this slot

+
+
+ ); + } + + return ( +
+ {/* Controls */} + +
+
+

Node Resources

+

CPU utilization across {nodeNames.length} nodes during this slot

+
+
+ + {!effectiveSelectedNode && ( + + )} +
+ + +
+
+
+
+ + {/* Chart */} + + + setShowRefNodeInfo(false)} /> +
+ ); +} diff --git a/src/pages/ethereum/slots/components/NodeResources/NodeSelector.tsx b/src/pages/ethereum/slots/components/NodeResources/NodeSelector.tsx new file mode 100644 index 000000000..638a08229 --- /dev/null +++ b/src/pages/ethereum/slots/components/NodeResources/NodeSelector.tsx @@ -0,0 +1,45 @@ +import type { JSX } from 'react'; +import { SelectMenu } from '@/components/Forms/SelectMenu'; +import { ClientLogo } from '@/components/Ethereum/ClientLogo'; + +export interface NodeClientInfo { + cl: string; + el: string; +} + +interface NodeSelectorProps { + nodes: string[]; + selectedNode: string | null; + onChange: (node: string | null) => void; + nodeClientInfo: Map; +} + +export function NodeSelector({ nodes, selectedNode, onChange, nodeClientInfo }: NodeSelectorProps): JSX.Element { + const options = [ + { value: '__all__', label: `All nodes (${nodes.length})` }, + ...nodes.map(node => { + const info = nodeClientInfo.get(node); + const shortName = node.split('/').pop() ?? node; + return { + value: node, + label: shortName, + icon: + info?.cl || info?.el ? ( + + {info.cl && } + {info.el && } + + ) : undefined, + }; + }), + ]; + + return ( + onChange(value === '__all__' ? null : value)} + options={options} + expandToFit + /> + ); +} diff --git a/src/pages/ethereum/slots/components/NodeResources/index.ts b/src/pages/ethereum/slots/components/NodeResources/index.ts new file mode 100644 index 000000000..c70f19632 --- /dev/null +++ b/src/pages/ethereum/slots/components/NodeResources/index.ts @@ -0,0 +1 @@ +export { NodeResourcesPanel } from './NodeResourcesPanel'; diff --git a/src/pages/ethereum/slots/hooks/useSlotNodeResources/index.ts b/src/pages/ethereum/slots/hooks/useSlotNodeResources/index.ts new file mode 100644 index 000000000..61141fa54 --- /dev/null +++ b/src/pages/ethereum/slots/hooks/useSlotNodeResources/index.ts @@ -0,0 +1,2 @@ +export { useSlotNodeResources } from './useSlotNodeResources'; +export type { UseSlotNodeResourcesResult } from './useSlotNodeResources'; diff --git a/src/pages/ethereum/slots/hooks/useSlotNodeResources/useSlotNodeResources.ts b/src/pages/ethereum/slots/hooks/useSlotNodeResources/useSlotNodeResources.ts new file mode 100644 index 000000000..d810d84dc --- /dev/null +++ b/src/pages/ethereum/slots/hooks/useSlotNodeResources/useSlotNodeResources.ts @@ -0,0 +1,38 @@ +import { useQuery } from '@tanstack/react-query'; +import { fctNodeCpuUtilizationServiceListOptions } from '@/api/@tanstack/react-query.gen'; +import { useNetwork } from '@/hooks/useNetwork'; +import { slotToTimestamp } from '@/utils/beacon'; +import type { FctNodeCpuUtilization } from '@/api/types.gen'; + +/** cbt-api returns DateTime64(3) fields as microseconds */ +const SECONDS_TO_MICROSECONDS = 1_000_000; + +export interface UseSlotNodeResourcesResult { + data: FctNodeCpuUtilization[] | null; + isLoading: boolean; + error: Error | null; +} + +export function useSlotNodeResources(slot: number): UseSlotNodeResourcesResult { + const { currentNetwork } = useNetwork(); + const slotTimestamp = currentNetwork ? slotToTimestamp(slot, currentNetwork.genesis_time) : 0; + const slotTimestampUs = slotTimestamp * SECONDS_TO_MICROSECONDS; + + const { data, isLoading, error } = useQuery({ + ...fctNodeCpuUtilizationServiceListOptions({ + query: { + wallclock_slot_start_date_time_eq: slotTimestampUs, + page_size: 10000, + }, + }), + enabled: !!currentNetwork && slotTimestamp > 0, + }); + + const cpuData = data?.fct_node_cpu_utilization ?? null; + + return { + data: cpuData, + isLoading, + error: error as Error | null, + }; +} diff --git a/src/routes/ethereum/slots/$slot.tsx b/src/routes/ethereum/slots/$slot.tsx index 25b5bcc5d..455442cdd 100644 --- a/src/routes/ethereum/slots/$slot.tsx +++ b/src/routes/ethereum/slots/$slot.tsx @@ -4,9 +4,12 @@ import { DetailPage } from '@/pages/ethereum/slots'; const slotSearchSchema = z.object({ tab: z - .enum(['overview', 'timeline', 'block', 'attestations', 'propagation', 'blobs', 'execution', 'mev']) + .enum(['overview', 'timeline', 'block', 'attestations', 'propagation', 'blobs', 'execution', 'mev', 'resources']) .default('overview'), contributor: z.string().optional(), + node: z.string().optional(), + metric: z.enum(['mean', 'min', 'max']).optional(), + refNodes: z.coerce.boolean().optional(), }); export const Route = createFileRoute('/ethereum/slots/$slot')({ From f749816f3f52e6dfff9c66559f1c045ca42414bd Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Thu, 12 Feb 2026 14:34:08 +1000 Subject: [PATCH 2/8] refactor: redesign CPU chart with min-max bands and clearer labels Replace 8 separate line series with shaded min-max bands and clean mean lines. Legend drops from 8 items to 2-4. "sys" terminology replaced with "% of all cores". Slot number added to subtitle. Peak core series hidden by default (toggle-able in legend). --- .../NodeResources/CpuUtilizationChart.tsx | 240 +++++++++++------- .../NodeResources/NodeResourcesPanel.tsx | 8 +- 2 files changed, 151 insertions(+), 97 deletions(-) diff --git a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx index ec6a5d9be..2ef69f9a1 100644 --- a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx @@ -22,19 +22,14 @@ function usToSeconds(us: number): number { return us / 1_000_000; } -/** Get the normalized metric value (0-100% of total system) from a data point */ -function getMetricValue(d: FctNodeCpuUtilization, metric: CpuMetric): number { - const cores = d.system_cores ?? 1; +function capitalize(s: string): string { + return s.charAt(0).toUpperCase() + s.slice(1); +} + +/** Normalize a metric value to % of total system CPU */ +function normalizeToSystem(value: number, cores: number): number { const divisor = cores > 0 ? cores : 1; - switch (metric) { - case 'min': - return (d.min_core_pct ?? 0) / divisor; - case 'max': - return (d.max_core_pct ?? 0) / divisor; - case 'mean': - default: - return (d.mean_core_pct ?? 0) / divisor; - } + return value / divisor; } const METRIC_LABELS: Record = { @@ -48,18 +43,32 @@ interface BlockArrival { node_id: string; } +/** Aggregated bucket data for a single time window */ +interface BucketAgg { + meanVals: number[]; + minVals: number[]; + maxVals: number[]; + coreVals: number[]; +} + interface CpuUtilizationChartProps { data: FctNodeCpuUtilization[]; selectedNode: string | null; blockPropagationData: BlockArrival[]; metric: CpuMetric; + slot: number; } +const BUCKET_SIZE = 0.25; +const toBucket = (offsetSec: number): number => Math.round(offsetSec / BUCKET_SIZE) * BUCKET_SIZE; +const avg = (arr: number[]): number => arr.reduce((s, v) => s + v, 0) / arr.length; + export function CpuUtilizationChart({ data, selectedNode, blockPropagationData, metric, + slot, }: CpuUtilizationChartProps): JSX.Element { const { CHART_CATEGORICAL_COLORS } = getDataVizColors(); @@ -68,56 +77,68 @@ export function CpuUtilizationChart({ return { series: [] as SeriesData[], markLines: [] as MarkLineConfig[], clClient: '', elClient: '' }; } - // Derive slot start time from data (microseconds) const slotStartUs = Math.min(...data.map(d => d.wallclock_slot_start_date_time ?? 0).filter(v => v > 0)); - const chartSeries: SeriesData[] = []; let resolvedClClient = ''; let resolvedElClient = ''; - // Bucket size for time aggregation (seconds) - const BUCKET_SIZE = 0.25; - const toBucket = (offsetSec: number): number => Math.round(offsetSec / BUCKET_SIZE) * BUCKET_SIZE; - - const buildLine = ( - items: FctNodeCpuUtilization[], - label: string, - color: string, - getValue: CpuMetric | ((d: FctNodeCpuUtilization) => number), - opts?: { - lineWidth?: number; - showArea?: boolean; - areaOpacity?: number; - lineStyle?: 'solid' | 'dashed' | 'dotted'; - } - ): void => { - const extractValue = - typeof getValue === 'function' ? getValue : (d: FctNodeCpuUtilization) => getMetricValue(d, getValue); - - const byBucket = new Map(); - items.forEach(d => { + /** Bucket data points by time offset, collecting all metric values per bucket */ + const bucketData = (items: FctNodeCpuUtilization[]): Map => { + const buckets = new Map(); + for (const d of items) { const offset = usToSeconds((d.window_start ?? 0) - slotStartUs); const bucket = toBucket(offset); - if (bucket < 0 || bucket > 12) return; - if (!byBucket.has(bucket)) byBucket.set(bucket, []); - byBucket.get(bucket)!.push(extractValue(d)); - }); + if (bucket < 0 || bucket > 12) continue; - const points = Array.from(byBucket.entries()) - .sort(([a], [b]) => a - b) - .map(([offset, values]) => [offset, values.reduce((s, v) => s + v, 0) / values.length] as [number, number]); - - if (points.length > 0) { - chartSeries.push({ - name: label, - data: points, - color, - lineWidth: opts?.lineWidth ?? 2, - showArea: opts?.showArea ?? true, - areaOpacity: opts?.areaOpacity ?? 0.08, - lineStyle: opts?.lineStyle, - }); + if (!buckets.has(bucket)) { + buckets.set(bucket, { meanVals: [], minVals: [], maxVals: [], coreVals: [] }); + } + const b = buckets.get(bucket)!; + const cores = d.system_cores ?? 1; + b.meanVals.push(normalizeToSystem(d.mean_core_pct ?? 0, cores)); + b.minVals.push(normalizeToSystem(d.min_core_pct ?? 0, cores)); + b.maxVals.push(normalizeToSystem(d.max_core_pct ?? 0, cores)); + b.coreVals.push(Math.min(d.max_core_pct ?? 0, 100)); } + return buckets; + }; + + /** Convert bucketed data to sorted [time, value] points */ + const toPoints = (buckets: Map, extract: (b: BucketAgg) => number[]): [number, number][] => + Array.from(buckets.entries()) + .sort(([a], [b]) => a - b) + .map(([t, b]) => [t, avg(extract(b))] as [number, number]); + + /** Add a band (min-max range) as two stacked series */ + const addBand = (buckets: Map, stackId: string, color: string): void => { + const sorted = Array.from(buckets.entries()).sort(([a], [b]) => a - b); + const basePoints = sorted.map(([t, b]) => [t, avg(b.minVals)] as [number, number]); + const widthPoints = sorted.map(([t, b]) => { + const lo = avg(b.minVals); + const hi = avg(b.maxVals); + return [t, Math.max(0, hi - lo)] as [number, number]; + }); + + chartSeries.push({ + name: `_${stackId}_base`, + data: basePoints, + stack: stackId, + showArea: true, + areaOpacity: 0, + lineWidth: 0, + color, + visible: false, + }); + chartSeries.push({ + name: `_${stackId}_width`, + data: widthPoints, + stack: stackId, + showArea: true, + areaOpacity: 0.12, + lineWidth: 0, + color, + visible: false, + }); }; if (selectedNode) { @@ -128,57 +149,90 @@ export function CpuUtilizationChart({ resolvedClClient = clData[0]?.client_type ?? ''; resolvedElClient = elData[0]?.client_type ?? ''; - const clLabel = resolvedClClient || 'CL'; - const elLabel = resolvedElClient || 'EL'; + const clLabel = capitalize(resolvedClClient || 'CL'); + const elLabel = capitalize(resolvedElClient || 'EL'); const clColor = CHART_CATEGORICAL_COLORS[0]; const elColor = CHART_CATEGORICAL_COLORS[1]; - const coreExtract = (d: FctNodeCpuUtilization) => Math.min(d.max_core_pct ?? 0, 100); + const clBuckets = bucketData(clData); + const elBuckets = bucketData(elData); - // CL system utilization: mean (solid), min (dotted), max (dashed) - buildLine(clData, `${clLabel} sys mean`, clColor, 'mean', { lineWidth: 2, showArea: true, areaOpacity: 0.06 }); - buildLine(clData, `${clLabel} sys min`, clColor, 'min', { - lineWidth: 1.5, - showArea: false, - lineStyle: 'dotted', - }); - buildLine(clData, `${clLabel} sys max`, clColor, 'max', { - lineWidth: 1.5, + // CL: min-max band, then mean line on top + addBand(clBuckets, 'cl_range', clColor); + chartSeries.push({ + name: `${clLabel}`, + data: toPoints(clBuckets, b => b.meanVals), + color: clColor, + lineWidth: 2, showArea: false, - lineStyle: 'dashed', }); - // EL system utilization: mean (solid), min (dotted), max (dashed) - buildLine(elData, `${elLabel} sys mean`, elColor, 'mean', { lineWidth: 2, showArea: true, areaOpacity: 0.06 }); - buildLine(elData, `${elLabel} sys min`, elColor, 'min', { - lineWidth: 1.5, + // EL: min-max band, then mean line on top + addBand(elBuckets, 'el_range', elColor); + chartSeries.push({ + name: `${elLabel}`, + data: toPoints(elBuckets, b => b.meanVals), + color: elColor, + lineWidth: 2, showArea: false, - lineStyle: 'dotted', - }); - buildLine(elData, `${elLabel} sys max`, elColor, 'max', { - lineWidth: 1.5, - showArea: false, - lineStyle: 'dashed', }); - // Hottest single core per client (raw, not divided by system_cores) - const singleCoreColor = CHART_CATEGORICAL_COLORS[2] ?? '#e5a00d'; - buildLine(clData, `${clLabel} hottest core`, singleCoreColor, coreExtract, { + // Busiest single core per client + chartSeries.push({ + name: `${clLabel} peak core`, + data: toPoints(clBuckets, b => b.coreVals), + color: clColor, lineWidth: 1.5, - showArea: false, lineStyle: 'dashed', + showArea: false, + initiallyVisible: false, }); - buildLine(elData, `${elLabel} hottest core`, singleCoreColor, coreExtract, { + chartSeries.push({ + name: `${elLabel} peak core`, + data: toPoints(elBuckets, b => b.coreVals), + color: elColor, lineWidth: 1.5, + lineStyle: 'dashed', showArea: false, - lineStyle: 'dotted', + initiallyVisible: false, }); } else { + // Aggregate view: CL/EL with selected metric const clData = data.filter(d => getClientLayer(d.client_type ?? '') === 'CL'); const elData = data.filter(d => getClientLayer(d.client_type ?? '') === 'EL'); - buildLine(clData, 'Consensus Layer', CHART_CATEGORICAL_COLORS[0], metric); - buildLine(elData, 'Execution Layer', CHART_CATEGORICAL_COLORS[1], metric); + const metricExtract = (b: BucketAgg): number[] => { + switch (metric) { + case 'min': + return b.minVals; + case 'max': + return b.maxVals; + case 'mean': + default: + return b.meanVals; + } + }; + + const clBuckets = bucketData(clData); + const elBuckets = bucketData(elData); + + addBand(clBuckets, 'cl_range', CHART_CATEGORICAL_COLORS[0]); + chartSeries.push({ + name: 'Consensus Layer', + data: toPoints(clBuckets, metricExtract), + color: CHART_CATEGORICAL_COLORS[0], + lineWidth: 2, + showArea: false, + }); + + addBand(elBuckets, 'el_range', CHART_CATEGORICAL_COLORS[1]); + chartSeries.push({ + name: 'Execution Layer', + data: toPoints(elBuckets, metricExtract), + color: CHART_CATEGORICAL_COLORS[1], + lineWidth: 2, + showArea: false, + }); } // Block arrival markLines @@ -235,8 +289,8 @@ export function CpuUtilizationChart({ const shortNodeName = selectedNode?.split('/').pop() ?? ''; const subtitle = selectedNode - ? `${shortNodeName} · sys% = total system, hottest core = single core peak` - : `${METRIC_LABELS[metric]} across ${nodeCount} nodes · % of total system`; + ? `Slot ${slot} · ${shortNodeName} · shaded = min/max range, dashed = busiest core` + : `Slot ${slot} · ${METRIC_LABELS[metric]} across ${nodeCount} nodes · % of all CPU cores`; const headerActions = selectedNode && (clClient || elClient) ? ( @@ -273,7 +327,7 @@ export function CpuUtilizationChart({ formatter: (v: number | string) => `${v}s`, }} yAxis={{ - name: 'CPU %', + name: '% of all cores', min: 0, formatter: (v: number) => `${v.toFixed(1)}%`, }} @@ -282,20 +336,24 @@ export function CpuUtilizationChart({ legendPosition="bottom" markLines={markLines} syncGroup="slot-time" - valueDecimals={1} tooltipFormatter={(params: unknown) => { const items = Array.isArray(params) ? params : [params]; if (items.length === 0) return ''; + // Filter out hidden band series from tooltip + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const visible = items.filter((p: any) => !String(p.seriesName).startsWith('_')); + if (visible.length === 0) return ''; + // eslint-disable-next-line @typescript-eslint/no-explicit-any - const first = items[0] as any; + const first = visible[0] as any; const xVal = Array.isArray(first.value) ? first.value[0] : first.axisValue; - const timeStr = typeof xVal === 'number' ? `${xVal.toFixed(3)}s` : `${xVal}s`; + const timeStr = typeof xVal === 'number' ? `${xVal.toFixed(2)}s` : `${xVal}s`; let html = `
`; html += `
${timeStr}
`; - for (const item of items) { + for (const item of visible) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const p = item as any; const val = Array.isArray(p.value) ? p.value[1] : p.value; diff --git a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx index 95311373d..fa9ac2328 100644 --- a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx @@ -167,12 +167,7 @@ export function NodeResourcesPanel({ slot, blockPropagationData }: NodeResources nodeClientInfo={nodeClientInfo} /> {!effectiveSelectedNode && ( - + )}
+ + {/* Annotation toggles */} + {availableAnnotations.length > 0 && ( +
+ Annotations: + {availableAnnotations.map(opt => ( + + ))} +
+ )} {/* Chart */} setShowRefNodeInfo(false)} /> diff --git a/src/pages/ethereum/slots/components/NodeResources/types.ts b/src/pages/ethereum/slots/components/NodeResources/types.ts new file mode 100644 index 000000000..b76494bf1 --- /dev/null +++ b/src/pages/ethereum/slots/components/NodeResources/types.ts @@ -0,0 +1,20 @@ +export type AnnotationType = 'block' | 'head' | 'execution' | 'data_columns'; + +export interface AnnotationEvent { + type: AnnotationType; + /** Time in milliseconds from slot start */ + timeMs: number; + /** Optional end time for range annotations */ + endMs?: number; + /** Optional label suffix */ + label?: string; + /** Node name this event belongs to (for filtering) */ + nodeName?: string; +} + +export const ANNOTATION_OPTIONS: { value: AnnotationType; label: string; description: string }[] = [ + { value: 'block', label: 'Block Arrival', description: 'When block gossip was received' }, + { value: 'head', label: 'Head Update', description: 'When chain head was updated' }, + { value: 'execution', label: 'Execution', description: 'Engine newPayload call duration' }, + { value: 'data_columns', label: 'Data Columns', description: 'First to last data column received' }, +]; From 1013d7153d4c774f6c9432bbd551ea9ca1484139 Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Thu, 12 Feb 2026 15:45:04 +1000 Subject: [PATCH 4/8] feat: add markArea annotations, slot phase boundaries, and UX improvements - Add markArea support to MultiLineChart (colored regions on chart) - Add slot phase boundary markLines (Block/Attestations/Aggregations) - Move metric dropdown into chart PopoutCard header - Change aggregate annotation ranges from p25-p75 to min-p95 - Fix double-toggle on annotation/7870 checkboxes (pointer-events-none) - Fix scroll-to-top on control changes (resetScroll: false) - Extract shared CL/EL client sets to utils/ethereum.ts - Update subtitle to link to Observoor repo --- src/components/Charts/MultiLine/MultiLine.tsx | 92 +++++--- .../Charts/MultiLine/MultiLine.types.ts | 33 +++ src/components/Charts/MultiLine/index.ts | 1 + .../NodeResources/CpuUtilizationChart.tsx | 209 ++++++++++++------ .../NodeResources/NodeResourcesPanel.tsx | 190 +++++++--------- .../slots/components/NodeResources/types.ts | 15 +- src/utils/ethereum.ts | 17 ++ 7 files changed, 345 insertions(+), 212 deletions(-) diff --git a/src/components/Charts/MultiLine/MultiLine.tsx b/src/components/Charts/MultiLine/MultiLine.tsx index e6c598b82..88f60025f 100644 --- a/src/components/Charts/MultiLine/MultiLine.tsx +++ b/src/components/Charts/MultiLine/MultiLine.tsx @@ -12,6 +12,7 @@ import { DataZoomComponent, LegendComponent, MarkLineComponent, + MarkAreaComponent, } from 'echarts/components'; import { CanvasRenderer } from 'echarts/renderers'; import { hexToRgba, formatSmartDecimal, getDataVizColors, resolveCssColorToHex } from '@/utils'; @@ -30,6 +31,7 @@ echarts.use([ DataZoomComponent, LegendComponent, MarkLineComponent, + MarkAreaComponent, CanvasRenderer, ]); @@ -95,6 +97,7 @@ export function MultiLineChart({ notMerge = true, onSeriesClick, markLines, + markAreas, }: MultiLineChartProps): React.JSX.Element { // Store ref to the ReactEChartsCore wrapper (not the instance) for click handling const chartWrapperRef = useRef(null); @@ -580,41 +583,73 @@ export function MultiLineChart({ return baseConfig; }); - // Add annotation series for markLines if provided + // Add annotation series for markLines/markAreas if provided + const hasMarkLines = markLines && markLines.length > 0; + const hasMarkAreas = markAreas && markAreas.length > 0; const annotationSeries = - markLines && markLines.length > 0 + hasMarkLines || hasMarkAreas ? [ { name: '__annotations__', type: 'line' as const, - data: [], // Empty data - this series is only for markLine + data: [], // Empty data - this series is only for annotations silent: true, // Don't trigger events legendHoverLink: false, - markLine: { - silent: true, - symbol: 'none', - animation: false, - data: markLines.map(ml => ({ - xAxis: ml.xValue, - label: { - show: !!ml.label, - formatter: ml.label ?? '', - position: ml.labelPosition ?? 'end', - rotate: -90, - align: 'left', - offset: [0, -2], - color: hexToRgba(ml.color ?? themeColors.muted, 0.7), - fontSize: 11, - backgroundColor: 'transparent', - padding: [2, 4], - }, - lineStyle: { - color: ml.color ?? themeColors.muted, - type: (ml.lineStyle ?? 'dashed') as 'solid' | 'dashed' | 'dotted', - width: ml.lineWidth ?? 1, - }, - })), - }, + ...(hasMarkLines + ? { + markLine: { + silent: true, + symbol: 'none', + animation: false, + data: markLines!.map(ml => ({ + xAxis: ml.xValue, + label: { + show: !!ml.label, + formatter: ml.label ?? '', + position: ml.labelPosition ?? 'end', + rotate: -90, + align: 'left', + offset: ml.distance ?? [0, -2], + color: hexToRgba(ml.color ?? themeColors.muted, 0.7), + fontSize: 11, + backgroundColor: 'transparent', + padding: [2, 4], + }, + lineStyle: { + color: ml.color ?? themeColors.muted, + type: (ml.lineStyle ?? 'dashed') as 'solid' | 'dashed' | 'dotted', + width: ml.lineWidth ?? 1, + }, + })), + }, + } + : {}), + ...(hasMarkAreas + ? { + markArea: { + silent: true, + animation: false, + data: markAreas!.map(ma => [ + { + xAxis: ma.xStart, + itemStyle: { + color: hexToRgba(ma.color ?? themeColors.muted, ma.opacity ?? 0.15), + }, + label: { + show: !!ma.label, + formatter: ma.label ?? '', + position: 'insideTop' as const, + color: hexToRgba(ma.color ?? themeColors.muted, 0.8), + fontSize: 10, + }, + }, + { + xAxis: ma.xEnd, + }, + ]), + }, + } + : {}), }, ] : []; @@ -861,6 +896,7 @@ export function MultiLineChart({ showLegend, legendPosition, markLines, + markAreas, ]); const chartContent = ( diff --git a/src/components/Charts/MultiLine/MultiLine.types.ts b/src/components/Charts/MultiLine/MultiLine.types.ts index a97bff90e..de14ab980 100644 --- a/src/components/Charts/MultiLine/MultiLine.types.ts +++ b/src/components/Charts/MultiLine/MultiLine.types.ts @@ -257,6 +257,34 @@ export interface MarkLineConfig { distance?: [number, number]; } +/** + * Configuration for a vertical annotation area (markArea) + * Renders a semi-transparent colored rectangle spanning the full y-axis + */ +export interface MarkAreaConfig { + /** + * Start x-axis value + */ + xStart: number | string; + /** + * End x-axis value + */ + xEnd: number | string; + /** + * Area color (hex or rgb) + */ + color?: string; + /** + * Area opacity (0-1) + * @default 0.15 + */ + opacity?: number; + /** + * Label to display inside the area + */ + label?: string; +} + /** * MultiLineChart component props */ @@ -410,4 +438,9 @@ export interface MultiLineChartProps { * Useful for marking important events like resurrections or thresholds */ markLines?: MarkLineConfig[]; + /** + * Vertical annotation areas to display on the chart + * Renders semi-transparent colored rectangles spanning the full y-axis + */ + markAreas?: MarkAreaConfig[]; } diff --git a/src/components/Charts/MultiLine/index.ts b/src/components/Charts/MultiLine/index.ts index 21e937e10..c97c7b739 100644 --- a/src/components/Charts/MultiLine/index.ts +++ b/src/components/Charts/MultiLine/index.ts @@ -1,6 +1,7 @@ export { MultiLineChart } from './MultiLine'; export type { EnrichedDataPoint, + MarkAreaConfig, MarkLineConfig, MultiLineChartProps, SeriesData, diff --git a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx index ab8834700..11854ded3 100644 --- a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx @@ -1,22 +1,13 @@ import { type JSX, useMemo } from 'react'; import { PopoutCard } from '@/components/Layout/PopoutCard'; import { MultiLineChart } from '@/components/Charts/MultiLine'; -import type { SeriesData, MarkLineConfig } from '@/components/Charts/MultiLine/MultiLine.types'; -import { getDataVizColors } from '@/utils'; +import type { SeriesData, MarkAreaConfig, MarkLineConfig } from '@/components/Charts/MultiLine/MultiLine.types'; +import { getDataVizColors, getClientLayer } from '@/utils'; +import { DEFAULT_BEACON_SLOT_PHASES } from '@/utils/beacon'; import { ClientLogo } from '@/components/Ethereum/ClientLogo'; +import { SelectMenu } from '@/components/Forms/SelectMenu'; import type { FctNodeCpuUtilization } from '@/api/types.gen'; -import type { CpuMetric } from './NodeResourcesPanel'; -import type { AnnotationType, AnnotationEvent } from './types'; - -const CL_CLIENTS = new Set(['lighthouse', 'lodestar', 'nimbus', 'prysm', 'teku', 'grandine']); -const EL_CLIENTS = new Set(['besu', 'erigon', 'geth', 'nethermind', 'reth']); - -function getClientLayer(clientType: string): 'CL' | 'EL' | null { - const lower = clientType.toLowerCase(); - if (CL_CLIENTS.has(lower)) return 'CL'; - if (EL_CLIENTS.has(lower)) return 'EL'; - return null; -} +import { ANNOTATION_COLORS, type CpuMetric, type AnnotationType, type AnnotationEvent } from './types'; function usToSeconds(us: number): number { return us / 1_000_000; @@ -37,19 +28,25 @@ const METRIC_LABELS: Record = { max: 'Max', }; -const ANNOTATION_COLORS: Record = { - block: '#f59e0b', - head: '#8b5cf6', - execution: '#ef4444', - data_columns: '#10b981', -}; +const METRIC_OPTIONS = [ + { value: 'mean' as CpuMetric, label: 'Mean' }, + { value: 'min' as CpuMetric, label: 'Min' }, + { value: 'max' as CpuMetric, label: 'Max' }, +]; -const ANNOTATION_LABELS: Record = { - block: 'Block', - head: 'Head', - execution: 'Exec', - data_columns: 'DA', -}; +/** Minimum width in seconds for point-event areas so they're visible */ +const MIN_AREA_WIDTH_SEC = 0.08; + +/** Match a CPU node name to propagation node_id (fuzzy matching) */ +function nodeMatches(cpuNodeName: string, propNodeId: string): boolean { + const short = cpuNodeName.split('/').pop() ?? cpuNodeName; + return propNodeId === short || propNodeId === cpuNodeName || short.includes(propNodeId) || propNodeId.includes(short); +} + +function percentile(sorted: number[], p: number): number { + const idx = Math.floor(sorted.length * p); + return sorted[Math.min(idx, sorted.length - 1)]; +} interface BucketAgg { meanVals: number[]; @@ -62,6 +59,7 @@ interface CpuUtilizationChartProps { data: FctNodeCpuUtilization[]; selectedNode: string | null; metric: CpuMetric; + onMetricChange: (metric: CpuMetric) => void; slot: number; annotations: AnnotationEvent[]; enabledAnnotations: Set; @@ -75,15 +73,16 @@ export function CpuUtilizationChart({ data, selectedNode, metric, + onMetricChange, slot, annotations, enabledAnnotations, }: CpuUtilizationChartProps): JSX.Element { const { CHART_CATEGORICAL_COLORS } = getDataVizColors(); - const { series, markLines, clClient, elClient } = useMemo(() => { + const { series, clClient, elClient } = useMemo(() => { if (data.length === 0) { - return { series: [] as SeriesData[], markLines: [] as MarkLineConfig[], clClient: '', elClient: '' }; + return { series: [] as SeriesData[], clClient: '', elClient: '' }; } const slotStartUs = Math.min(...data.map(d => d.wallclock_slot_start_date_time ?? 0).filter(v => v > 0)); @@ -144,7 +143,6 @@ export function CpuUtilizationChart({ const clBuckets = bucketData(clData); const elBuckets = bucketData(elData); - // CL mean line with gradient fill chartSeries.push({ name: clLabel, data: toPoints(clBuckets, b => b.meanVals), @@ -154,7 +152,6 @@ export function CpuUtilizationChart({ areaOpacity: 0.08, }); - // EL mean line with gradient fill chartSeries.push({ name: elLabel, data: toPoints(elBuckets, b => b.meanVals), @@ -164,7 +161,6 @@ export function CpuUtilizationChart({ areaOpacity: 0.08, }); - // Peak core (hidden by default) chartSeries.push({ name: `${clLabel} peak core`, data: toPoints(clBuckets, b => b.coreVals), @@ -209,51 +205,118 @@ export function CpuUtilizationChart({ }); } - // Build annotation markLines - const chartMarkLines: MarkLineConfig[] = []; - - for (const anno of annotations) { - if (!enabledAnnotations.has(anno.type)) continue; + return { series: chartSeries, clClient: resolvedClClient, elClient: resolvedElClient }; + }, [data, selectedNode, metric, CHART_CATEGORICAL_COLORS]); - const timeSec = anno.timeMs / 1000; - if (timeSec < 0 || timeSec > 12) continue; + // Convert annotations to markAreas (chart handles node matching + aggregation) + const markAreas = useMemo((): MarkAreaConfig[] => { + const areas: MarkAreaConfig[] = []; - const color = ANNOTATION_COLORS[anno.type]; - const prefix = ANNOTATION_LABELS[anno.type]; - const label = anno.label ? `${prefix}: ${anno.label}` : prefix; - - if (anno.endMs != null) { - // Range annotation: show start and end markLines - const endSec = anno.endMs / 1000; - if (endSec >= 0 && endSec <= 12) { - chartMarkLines.push({ - xValue: timeSec, - label: `${label} start`, - color, - lineStyle: 'dashed', - lineWidth: 1, - }); - chartMarkLines.push({ - xValue: endSec, - label: `${label} end`, + if (selectedNode) { + // Single node: find matching events and render exact positions + for (const anno of annotations) { + if (!enabledAnnotations.has(anno.type)) continue; + if (!anno.nodeName || !nodeMatches(selectedNode, anno.nodeName)) continue; + + const startSec = anno.timeMs / 1000; + if (startSec < 0 || startSec > 12) continue; + const color = ANNOTATION_COLORS[anno.type]; + const hasRange = anno.endMs != null && Math.abs(anno.endMs - anno.timeMs) > 10; + + if (hasRange) { + const endSec = Math.min(anno.endMs! / 1000, 12); + areas.push({ xStart: startSec, xEnd: endSec, color, opacity: 0.12 }); + } else { + areas.push({ + xStart: startSec - MIN_AREA_WIDTH_SEC / 2, + xEnd: startSec + MIN_AREA_WIDTH_SEC / 2, color, - lineStyle: 'dashed', - lineWidth: 1, + opacity: 0.3, }); } - } else { - chartMarkLines.push({ - xValue: timeSec, - label, - color, - lineStyle: 'dashed', - lineWidth: 1, - }); } + } else { + // Aggregate: compute min–p95 range per annotation type + const byType = new Map(); + for (const anno of annotations) { + if (!enabledAnnotations.has(anno.type)) continue; + if (!byType.has(anno.type)) byType.set(anno.type, []); + byType.get(anno.type)!.push(anno); + } + + for (const [type, events] of byType) { + const color = ANNOTATION_COLORS[type]; + const hasRanges = events.some(e => e.endMs != null); + + if (hasRanges) { + // Range events (execution, data_columns): min of starts → p95 of ends + const starts = events.map(e => e.timeMs).sort((a, b) => a - b); + const ends = events.map(e => e.endMs ?? e.timeMs).sort((a, b) => a - b); + const startSec = starts[0] / 1000; + const endSec = percentile(ends, 0.95) / 1000; + if (startSec >= 0 && startSec <= 12) { + areas.push({ + xStart: Math.max(0, startSec), + xEnd: Math.min(12, endSec), + color, + opacity: 0.1, + }); + } + } else { + // Point events (block, head): min–p95 spread as area + const times = events.map(e => e.timeMs).sort((a, b) => a - b); + const minSec = times[0] / 1000; + const p95Sec = percentile(times, 0.95) / 1000; + if (minSec >= 0 && p95Sec <= 12) { + const width = p95Sec - minSec; + if (width < MIN_AREA_WIDTH_SEC) { + // Very tight spread: render as thin band at median + const medSec = percentile(times, 0.5) / 1000; + areas.push({ + xStart: medSec - MIN_AREA_WIDTH_SEC / 2, + xEnd: medSec + MIN_AREA_WIDTH_SEC / 2, + color, + opacity: 0.25, + }); + } else { + areas.push({ xStart: minSec, xEnd: p95Sec, color, opacity: 0.1 }); + } + } + } + } + } + + return areas; + }, [annotations, enabledAnnotations, selectedNode]); + + // Slot phase boundary markLines (e.g. attestation deadline at 4s, aggregation at 8s) + // Colors match the live slot view: cyan (block), green (attestation), amber (aggregation) + const PHASE_BOUNDARY_COLORS = ['#22d3ee', '#22c55e', '#f59e0b']; + + const markLines = useMemo((): MarkLineConfig[] => { + if (!enabledAnnotations.has('slot_phases')) return []; + + const lines: MarkLineConfig[] = []; + let cumulativeSec = 0; + + for (let i = 0; i < DEFAULT_BEACON_SLOT_PHASES.length - 1; i++) { + cumulativeSec += DEFAULT_BEACON_SLOT_PHASES[i].duration / 1000; + const nextPhase = DEFAULT_BEACON_SLOT_PHASES[i + 1]; + const color = PHASE_BOUNDARY_COLORS[i + 1] ?? '#6b7280'; + + lines.push({ + xValue: cumulativeSec, + label: nextPhase.label, + labelPosition: 'insideEndTop', + color, + lineStyle: 'dotted', + lineWidth: 1, + distance: [0, -8], + }); } - return { series: chartSeries, markLines: chartMarkLines, clClient: resolvedClClient, elClient: resolvedElClient }; - }, [data, selectedNode, metric, CHART_CATEGORICAL_COLORS, annotations, enabledAnnotations]); + return lines; + }, [enabledAnnotations]); const nodeCount = new Set(data.map(d => d.meta_client_name)).size; const shortNodeName = selectedNode?.split('/').pop() ?? ''; @@ -262,13 +325,16 @@ export function CpuUtilizationChart({ ? `Slot ${slot} · ${shortNodeName} · % of all CPU cores` : `Slot ${slot} · ${METRIC_LABELS[metric]} across ${nodeCount} nodes · % of all CPU cores`; - const headerActions = - selectedNode && (clClient || elClient) ? ( + const headerActions = selectedNode ? ( + clClient || elClient ? (
{clClient && } {elClient && }
- ) : undefined; + ) : undefined + ) : ( + + ); if (data.length === 0) { return ( @@ -305,6 +371,7 @@ export function CpuUtilizationChart({ showLegend legendPosition="bottom" markLines={markLines} + markAreas={markAreas} syncGroup="slot-time" tooltipFormatter={(params: unknown) => { const items = Array.isArray(params) ? params : [params]; diff --git a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx index 49bbf6e93..147a778ff 100644 --- a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx @@ -4,9 +4,9 @@ import { useQuery } from '@tanstack/react-query'; import { InformationCircleIcon } from '@heroicons/react/24/outline'; import { Card } from '@/components/Layout/Card'; import { Checkbox } from '@/components/Forms/Checkbox'; -import { SelectMenu } from '@/components/Forms/SelectMenu'; import { ReferenceNodesInfoDialog } from '@/pages/ethereum/execution/timings/components/ReferenceNodesInfoDialog'; import { extractClusterFromNodeName } from '@/constants/eip7870'; +import { CONSENSUS_CLIENTS, EXECUTION_CLIENTS_SET } from '@/utils/ethereum'; import { intEngineNewPayloadServiceListOptions } from '@/api/@tanstack/react-query.gen'; import type { FctBlockFirstSeenByNode, @@ -16,12 +16,15 @@ import type { import { useSlotNodeResources } from '../../hooks/useSlotNodeResources'; import { NodeSelector, type NodeClientInfo } from './NodeSelector'; import { CpuUtilizationChart } from './CpuUtilizationChart'; -import { ANNOTATION_OPTIONS, type AnnotationType, type AnnotationEvent } from './types'; +import { + ANNOTATION_OPTIONS, + ANNOTATION_COLORS, + type CpuMetric, + type AnnotationType, + type AnnotationEvent, +} from './types'; -export type CpuMetric = 'mean' | 'min' | 'max'; - -const CL_CLIENTS = new Set(['lighthouse', 'lodestar', 'nimbus', 'prysm', 'teku', 'grandine']); -const EL_CLIENTS = new Set(['besu', 'erigon', 'geth', 'nethermind', 'reth']); +export type { CpuMetric } from './types'; interface NodeResourcesPanelProps { slot: number; @@ -30,18 +33,6 @@ interface NodeResourcesPanelProps { dataColumnPropagation: FctBlockDataColumnSidecarFirstSeenByNode[]; } -const METRIC_OPTIONS = [ - { value: 'mean' as CpuMetric, label: 'Mean' }, - { value: 'min' as CpuMetric, label: 'Min' }, - { value: 'max' as CpuMetric, label: 'Max' }, -]; - -/** Match a CPU node name to propagation node_id (fuzzy matching) */ -function nodeMatches(cpuNodeName: string, propNodeId: string): boolean { - const short = cpuNodeName.split('/').pop() ?? cpuNodeName; - return propNodeId === short || propNodeId === cpuNodeName || short.includes(propNodeId) || propNodeId.includes(short); -} - export function NodeResourcesPanel({ slot, blockPropagation, @@ -53,7 +44,7 @@ export function NodeResourcesPanel({ const navigate = useNavigate(); const [showRefNodeInfo, setShowRefNodeInfo] = useState(false); const [enabledAnnotations, setEnabledAnnotations] = useState>( - () => new Set(['block', 'head', 'execution', 'data_columns']) + () => new Set(['slot_phases', 'block', 'head', 'execution', 'data_columns']) ); // Always fetch execution timing data so the toggle can show availability @@ -78,6 +69,7 @@ export function NodeResourcesPanel({ params: { slot: String(slot) }, search: prev => ({ ...prev, refNodes: value || undefined }), replace: true, + resetScroll: false, }); }, [navigate, slot] @@ -90,6 +82,7 @@ export function NodeResourcesPanel({ params: { slot: String(slot) }, search: prev => ({ ...prev, node: value ?? undefined }), replace: true, + resetScroll: false, }); }, [navigate, slot] @@ -102,6 +95,7 @@ export function NodeResourcesPanel({ params: { slot: String(slot) }, search: prev => ({ ...prev, metric: value === 'mean' ? undefined : value }), replace: true, + resetScroll: false, }); }, [navigate, slot] @@ -143,9 +137,9 @@ export function NodeResourcesPanel({ if (!name) continue; const existing = info.get(name) ?? { cl: '', el: '' }; - if (CL_CLIENTS.has(clientType) && !existing.cl) { + if (CONSENSUS_CLIENTS.has(clientType) && !existing.cl) { existing.cl = clientType; - } else if (EL_CLIENTS.has(clientType) && !existing.el) { + } else if (EXECUTION_CLIENTS_SET.has(clientType) && !existing.el) { existing.el = clientType; } info.set(name, existing); @@ -156,105 +150,66 @@ export function NodeResourcesPanel({ // Reset selected node if it's no longer in the filtered list const effectiveSelectedNode = selectedNode && nodeNames.includes(selectedNode) ? selectedNode : null; - // Build annotations from propagation data + // Build raw per-node annotation events (chart handles aggregation) const annotations = useMemo((): AnnotationEvent[] => { const events: AnnotationEvent[] = []; - if (effectiveSelectedNode) { - // Single node: show exact events for this node - for (const p of blockPropagation) { - if (p.node_id && nodeMatches(effectiveSelectedNode, p.node_id)) { - events.push({ type: 'block', timeMs: p.seen_slot_start_diff ?? 0, nodeName: effectiveSelectedNode }); - break; - } - } - - for (const p of headPropagation) { - if (p.node_id && nodeMatches(effectiveSelectedNode, p.node_id)) { - events.push({ type: 'head', timeMs: p.seen_slot_start_diff ?? 0, nodeName: effectiveSelectedNode }); - break; - } + for (const p of blockPropagation) { + if (p.node_id) { + events.push({ type: 'block', timeMs: p.seen_slot_start_diff ?? 0, nodeName: p.node_id }); } + } - // Execution timing for this node - const execItems = executionData?.int_engine_new_payload ?? []; - for (const e of execItems) { - if (e.meta_client_name && nodeMatches(effectiveSelectedNode, e.meta_client_name)) { - const slotStartMs = (e.slot_start_date_time ?? 0) * 1000; - const requestedMs = (e.requested_date_time ?? 0) / 1000; - const startMs = requestedMs - slotStartMs; - const durationMs = e.duration_ms ?? 0; - events.push({ - type: 'execution', - timeMs: startMs, - endMs: startMs + durationMs, - label: `${durationMs.toFixed(0)}ms`, - nodeName: effectiveSelectedNode, - }); - break; - } + for (const p of headPropagation) { + if (p.node_id) { + events.push({ type: 'head', timeMs: p.seen_slot_start_diff ?? 0, nodeName: p.node_id }); } + } - // Data columns: range from first to last column seen - const nodeColumns = dataColumnPropagation.filter(p => p.node_id && nodeMatches(effectiveSelectedNode, p.node_id)); - if (nodeColumns.length > 0) { - const times = nodeColumns.map(c => c.seen_slot_start_diff ?? 0); - const minTime = Math.min(...times); - const maxTime = Math.max(...times); + const execItems = executionData?.int_engine_new_payload ?? []; + for (const e of execItems) { + if (e.meta_client_name) { + const slotStartMs = (e.slot_start_date_time ?? 0) * 1000; + const requestedMs = (e.requested_date_time ?? 0) / 1000; + const startMs = requestedMs - slotStartMs; + const durationMs = e.duration_ms ?? 0; events.push({ - type: 'data_columns', - timeMs: minTime, - endMs: minTime !== maxTime ? maxTime : undefined, - label: `${nodeColumns.length} cols`, - nodeName: effectiveSelectedNode, + type: 'execution', + timeMs: startMs, + endMs: startMs + durationMs, + label: `${durationMs.toFixed(0)}ms`, + nodeName: e.meta_client_name, }); } - } else { - // Aggregate: show p50 for block/head, nothing for execution/data_columns - const blockTimes = blockPropagation.map(p => p.seen_slot_start_diff ?? 0).sort((a, b) => a - b); - if (blockTimes.length > 0) { - events.push({ type: 'block', timeMs: blockTimes[Math.floor(blockTimes.length * 0.5)], label: 'p50' }); - } - - const headTimes = headPropagation.map(p => p.seen_slot_start_diff ?? 0).sort((a, b) => a - b); - if (headTimes.length > 0) { - events.push({ type: 'head', timeMs: headTimes[Math.floor(headTimes.length * 0.5)], label: 'p50' }); - } + } - // Data columns aggregate: p50 of first-seen, p50 of last-seen - if (dataColumnPropagation.length > 0) { - const byNode = new Map(); - for (const c of dataColumnPropagation) { - const nid = c.node_id ?? ''; - if (!byNode.has(nid)) byNode.set(nid, []); - byNode.get(nid)!.push(c.seen_slot_start_diff ?? 0); - } - const firstTimes: number[] = []; - const lastTimes: number[] = []; - for (const times of byNode.values()) { - firstTimes.push(Math.min(...times)); - lastTimes.push(Math.max(...times)); - } - firstTimes.sort((a, b) => a - b); - lastTimes.sort((a, b) => a - b); - const firstP50 = firstTimes[Math.floor(firstTimes.length * 0.5)]; - const lastP50 = lastTimes[Math.floor(lastTimes.length * 0.5)]; - events.push({ - type: 'data_columns', - timeMs: firstP50, - endMs: firstP50 !== lastP50 ? lastP50 : undefined, - label: 'p50', - }); - } + // Data columns: group by node, produce one range event per node + const colsByNode = new Map(); + for (const c of dataColumnPropagation) { + const nid = c.node_id ?? ''; + if (!nid) continue; + if (!colsByNode.has(nid)) colsByNode.set(nid, []); + colsByNode.get(nid)!.push(c.seen_slot_start_diff ?? 0); + } + for (const [nid, times] of colsByNode) { + const minTime = Math.min(...times); + const maxTime = Math.max(...times); + events.push({ + type: 'data_columns', + timeMs: minTime, + endMs: minTime !== maxTime ? maxTime : undefined, + label: `${times.length} cols`, + nodeName: nid, + }); } return events; - }, [effectiveSelectedNode, blockPropagation, headPropagation, dataColumnPropagation, executionData]); + }, [blockPropagation, headPropagation, dataColumnPropagation, executionData]); - // Which annotation types have data + // Which annotation types have data (slot_phases is always available) const availableAnnotations = useMemo(() => { const types = new Set(annotations.map(a => a.type)); - return ANNOTATION_OPTIONS.filter(o => types.has(o.value)); + return ANNOTATION_OPTIONS.filter(o => o.value === 'slot_phases' || types.has(o.value)); }, [annotations]); if (isLoading) { @@ -293,13 +248,24 @@ export function NodeResourcesPanel({ } return ( -
+
{/* Controls */}

Node Resources

-

CPU utilization across {nodeNames.length} nodes during this slot

+

+ Data from{' '} + + Observoor + {' '} + across {nodeNames.length} nodes +

- {!effectiveSelectedNode && ( - - )}
))} @@ -356,6 +323,7 @@ export function NodeResourcesPanel({ data={filteredData} selectedNode={effectiveSelectedNode} metric={metric} + onMetricChange={setMetric} slot={slot} annotations={annotations} enabledAnnotations={enabledAnnotations} diff --git a/src/pages/ethereum/slots/components/NodeResources/types.ts b/src/pages/ethereum/slots/components/NodeResources/types.ts index b76494bf1..5c4c2f473 100644 --- a/src/pages/ethereum/slots/components/NodeResources/types.ts +++ b/src/pages/ethereum/slots/components/NodeResources/types.ts @@ -1,7 +1,9 @@ -export type AnnotationType = 'block' | 'head' | 'execution' | 'data_columns'; +export type CpuMetric = 'mean' | 'min' | 'max'; + +export type AnnotationType = 'block' | 'head' | 'execution' | 'data_columns' | 'slot_phases'; export interface AnnotationEvent { - type: AnnotationType; + type: Exclude; /** Time in milliseconds from slot start */ timeMs: number; /** Optional end time for range annotations */ @@ -12,7 +14,16 @@ export interface AnnotationEvent { nodeName?: string; } +export const ANNOTATION_COLORS: Record = { + block: '#f59e0b', + head: '#8b5cf6', + execution: '#ef4444', + data_columns: '#10b981', + slot_phases: '#6b7280', +}; + export const ANNOTATION_OPTIONS: { value: AnnotationType; label: string; description: string }[] = [ + { value: 'slot_phases', label: 'Slot Phases', description: 'Block / Attestation / Aggregation phase boundaries' }, { value: 'block', label: 'Block Arrival', description: 'When block gossip was received' }, { value: 'head', label: 'Head Update', description: 'When chain head was updated' }, { value: 'execution', label: 'Execution', description: 'Engine newPayload call duration' }, diff --git a/src/utils/ethereum.ts b/src/utils/ethereum.ts index 6d288e13c..dffc1e465 100644 --- a/src/utils/ethereum.ts +++ b/src/utils/ethereum.ts @@ -97,9 +97,26 @@ export function truncateAddress(pubkey?: string, startChars = 6, endChars = 4): return `${pubkey.slice(0, startChars)}...${pubkey.slice(-endChars)}`; } +/** + * Known consensus client names + */ +export const CONSENSUS_CLIENTS = new Set(['lighthouse', 'lodestar', 'nimbus', 'prysm', 'teku', 'grandine']); + /** * Known execution client names */ +export const EXECUTION_CLIENTS_SET = new Set(['besu', 'erigon', 'geth', 'nethermind', 'reth', 'ethrex']); + +/** + * Determine whether a client type string is a CL or EL client + */ +export function getClientLayer(clientType: string): 'CL' | 'EL' | null { + const lower = clientType.toLowerCase(); + if (CONSENSUS_CLIENTS.has(lower)) return 'CL'; + if (EXECUTION_CLIENTS_SET.has(lower)) return 'EL'; + return null; +} + const EXECUTION_CLIENTS = ['geth', 'nethermind', 'besu', 'erigon', 'reth', 'ethrex'] as const; /** From ab84241266a9bbe8e47769490e0210759d5253b7 Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Thu, 12 Feb 2026 16:26:12 +1000 Subject: [PATCH 5/8] fix: resolve build and lint errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update IntEngineNewPayloadFastest → IntEngineNewPayloadFastestExecutionByNodeClass after table rename (pre-existing master issue) - Fix navigate type narrowing by using search spread instead of prev callback - Replace any casts with EChartsTooltipParam interface in tooltip formatter - Move PHASE_BOUNDARY_COLORS to module scope to fix exhaustive-deps warning - Regenerate API types from local cbt-api (removes stale max_single_core_pct) --- src/api/types.gen.ts | 8 ------- src/api/zod.gen.ts | 2 -- .../NewPayloadTab/NewPayloadTab.tsx | 4 ++-- .../timings/hooks/useEngineTimingsData.ts | 10 ++++---- .../NodeResources/CpuUtilizationChart.tsx | 23 +++++++++++-------- .../NodeResources/NodeResourcesPanel.tsx | 12 +++++----- 6 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/api/types.gen.ts b/src/api/types.gen.ts index 4c7cd6b42..f2a4b6bb9 100644 --- a/src/api/types.gen.ts +++ b/src/api/types.gen.ts @@ -4569,10 +4569,6 @@ export type FctNodeCpuUtilization = { * Maximum CPU core utilization percentage (100pct = 1 core) */ max_core_pct?: number; - /** - * Maximum single core utilization percentage (0-100pct) - */ - max_single_core_pct?: number; /** * Mean CPU core utilization percentage (100pct = 1 core) */ @@ -55469,10 +55465,6 @@ export type FctNodeCpuUtilizationServiceListData = { * Filter max_core_pct using value */ max_core_pct_value?: number; - /** - * Filter max_single_core_pct using value - */ - max_single_core_pct_value?: number; /** * Node classification for filtering (e.g. eip7870) (filter: eq) */ diff --git a/src/api/zod.gen.ts b/src/api/zod.gen.ts index 8629aa971..04009bf32 100644 --- a/src/api/zod.gen.ts +++ b/src/api/zod.gen.ts @@ -6634,7 +6634,6 @@ export const zFctNodeActiveLast24h = z.object({ export const zFctNodeCpuUtilization = z.object({ client_type: z.optional(z.string()), max_core_pct: z.optional(z.number()), - max_single_core_pct: z.optional(z.number()), mean_core_pct: z.optional(z.number()), meta_client_name: z.optional(z.string()), meta_network_name: z.optional(z.string()), @@ -69462,7 +69461,6 @@ export const zFctNodeCpuUtilizationServiceListData = z.object({ mean_core_pct_value: z.optional(z.number()), min_core_pct_value: z.optional(z.number()), max_core_pct_value: z.optional(z.number()), - max_single_core_pct_value: z.optional(z.number()), node_class_eq: z.optional(z.string()), node_class_ne: z.optional(z.string()), node_class_contains: z.optional(z.string()), diff --git a/src/pages/ethereum/execution/timings/components/NewPayloadTab/NewPayloadTab.tsx b/src/pages/ethereum/execution/timings/components/NewPayloadTab/NewPayloadTab.tsx index 9ac23028d..2fbb61ab0 100644 --- a/src/pages/ethereum/execution/timings/components/NewPayloadTab/NewPayloadTab.tsx +++ b/src/pages/ethereum/execution/timings/components/NewPayloadTab/NewPayloadTab.tsx @@ -10,7 +10,7 @@ import { ScatterAndLineChart } from '@/components/Charts/ScatterAndLine'; import { useThemeColors } from '@/hooks/useThemeColors'; import { formatSlot, getExecutionClientColor } from '@/utils'; import { ClientLogo } from '@/components/Ethereum/ClientLogo'; -import type { FctEngineNewPayloadWinrateHourly, IntEngineNewPayloadFastest } from '@/api/types.gen'; +import type { FctEngineNewPayloadWinrateHourly, IntEngineNewPayloadFastestExecutionByNodeClass } from '@/api/types.gen'; import type { EngineTimingsData } from '../../hooks/useEngineTimingsData'; import { PER_SLOT_CHART_RANGES, type TimeRange } from '../../IndexPage.types'; import { ClientVersionBreakdown } from '../ClientVersionBreakdown'; @@ -833,7 +833,7 @@ function WinrateSection({ showPerSlot, }: { hourlyRecords: FctEngineNewPayloadWinrateHourly[]; - perSlotRecords: IntEngineNewPayloadFastest[]; + perSlotRecords: IntEngineNewPayloadFastestExecutionByNodeClass[]; allClients: string[]; timeRange: TimeRange; showPerSlot: boolean; diff --git a/src/pages/ethereum/execution/timings/hooks/useEngineTimingsData.ts b/src/pages/ethereum/execution/timings/hooks/useEngineTimingsData.ts index 6b08dd9d7..934913314 100644 --- a/src/pages/ethereum/execution/timings/hooks/useEngineTimingsData.ts +++ b/src/pages/ethereum/execution/timings/hooks/useEngineTimingsData.ts @@ -8,7 +8,7 @@ import { fctEngineGetBlobsByElClientHourlyServiceList, fctEngineGetBlobsDurationChunked50MsServiceList, fctEngineNewPayloadWinrateHourlyServiceList, - intEngineNewPayloadFastestServiceList, + intEngineNewPayloadFastestExecutionByNodeClassServiceList, } from '@/api/sdk.gen'; import type { FctEngineNewPayloadByElClient, @@ -18,7 +18,7 @@ import type { FctEngineGetBlobsByElClientHourly, FctEngineGetBlobsDurationChunked50Ms, FctEngineNewPayloadWinrateHourly, - IntEngineNewPayloadFastest, + IntEngineNewPayloadFastestExecutionByNodeClass, } from '@/api/types.gen'; import { useNetwork } from '@/hooks/useNetwork'; import { fetchAllPages } from '@/utils/api-pagination'; @@ -47,7 +47,7 @@ export interface EngineTimingsData { winrateHourly: FctEngineNewPayloadWinrateHourly[]; // newPayload winrate (per-slot, for short time ranges) - winratePerSlot: IntEngineNewPayloadFastest[]; + winratePerSlot: IntEngineNewPayloadFastestExecutionByNodeClass[]; } export type ActiveTab = 'newPayload' | 'getBlobs'; @@ -275,8 +275,8 @@ export function useEngineTimingsData({ { queryKey: ['engine-timings', 'winrate-per-slot', hourlyStart, hourlyEnd, referenceNodesOnly], queryFn: ({ signal }) => - fetchAllPages( - intEngineNewPayloadFastestServiceList, + fetchAllPages( + intEngineNewPayloadFastestExecutionByNodeClassServiceList, { query: { slot_start_date_time_gte: hourlyStart, diff --git a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx index 11854ded3..2702b9549 100644 --- a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx @@ -65,6 +65,16 @@ interface CpuUtilizationChartProps { enabledAnnotations: Set; } +/** Slot phase boundary colors: cyan (block), green (attestation), amber (aggregation) */ +const PHASE_BOUNDARY_COLORS = ['#22d3ee', '#22c55e', '#f59e0b']; + +interface EChartsTooltipParam { + marker: string; + seriesName: string; + value: [number, number] | number; + axisValue?: number | string; +} + const BUCKET_SIZE = 0.25; const toBucket = (offsetSec: number): number => Math.round(offsetSec / BUCKET_SIZE) * BUCKET_SIZE; const avg = (arr: number[]): number => arr.reduce((s, v) => s + v, 0) / arr.length; @@ -289,10 +299,6 @@ export function CpuUtilizationChart({ return areas; }, [annotations, enabledAnnotations, selectedNode]); - // Slot phase boundary markLines (e.g. attestation deadline at 4s, aggregation at 8s) - // Colors match the live slot view: cyan (block), green (attestation), amber (aggregation) - const PHASE_BOUNDARY_COLORS = ['#22d3ee', '#22c55e', '#f59e0b']; - const markLines = useMemo((): MarkLineConfig[] => { if (!enabledAnnotations.has('slot_phases')) return []; @@ -374,20 +380,17 @@ export function CpuUtilizationChart({ markAreas={markAreas} syncGroup="slot-time" tooltipFormatter={(params: unknown) => { - const items = Array.isArray(params) ? params : [params]; + const items = (Array.isArray(params) ? params : [params]) as EChartsTooltipParam[]; if (items.length === 0) return ''; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const first = items[0] as any; + const first = items[0]; const xVal = Array.isArray(first.value) ? first.value[0] : first.axisValue; const timeStr = typeof xVal === 'number' ? `${xVal.toFixed(2)}s` : `${xVal}s`; let html = `
`; html += `
${timeStr}
`; - for (const item of items) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const p = item as any; + for (const p of items) { const val = Array.isArray(p.value) ? p.value[1] : p.value; if (val == null) continue; html += `
`; diff --git a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx index 147a778ff..f976ff009 100644 --- a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx @@ -67,12 +67,12 @@ export function NodeResourcesPanel({ navigate({ to: '/ethereum/slots/$slot', params: { slot: String(slot) }, - search: prev => ({ ...prev, refNodes: value || undefined }), + search: { ...search, refNodes: value || undefined }, replace: true, resetScroll: false, }); }, - [navigate, slot] + [navigate, slot, search] ); const setSelectedNode = useCallback( @@ -80,12 +80,12 @@ export function NodeResourcesPanel({ navigate({ to: '/ethereum/slots/$slot', params: { slot: String(slot) }, - search: prev => ({ ...prev, node: value ?? undefined }), + search: { ...search, node: value ?? undefined }, replace: true, resetScroll: false, }); }, - [navigate, slot] + [navigate, slot, search] ); const setMetric = useCallback( @@ -93,12 +93,12 @@ export function NodeResourcesPanel({ navigate({ to: '/ethereum/slots/$slot', params: { slot: String(slot) }, - search: prev => ({ ...prev, metric: value === 'mean' ? undefined : value }), + search: { ...search, metric: value === 'mean' ? undefined : value }, replace: true, resetScroll: false, }); }, - [navigate, slot] + [navigate, slot, search] ); const toggleAnnotation = useCallback((type: AnnotationType) => { From 79bf6e9d1d41f6212aada2315286b4fdd7d9b5b8 Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Thu, 12 Feb 2026 17:03:25 +1000 Subject: [PATCH 6/8] refactor: deduplicate client name lists into single source of truth --- .../components/NodeResources/NodeResourcesPanel.tsx | 4 ++-- .../xatu/locally-built-blocks/utils/parse-clients.ts | 10 +--------- src/utils/ethereum.ts | 10 +++++----- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx index f976ff009..605130de7 100644 --- a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx @@ -6,7 +6,7 @@ import { Card } from '@/components/Layout/Card'; import { Checkbox } from '@/components/Forms/Checkbox'; import { ReferenceNodesInfoDialog } from '@/pages/ethereum/execution/timings/components/ReferenceNodesInfoDialog'; import { extractClusterFromNodeName } from '@/constants/eip7870'; -import { CONSENSUS_CLIENTS, EXECUTION_CLIENTS_SET } from '@/utils/ethereum'; +import { CONSENSUS_CLIENTS_SET, EXECUTION_CLIENTS_SET } from '@/utils/ethereum'; import { intEngineNewPayloadServiceListOptions } from '@/api/@tanstack/react-query.gen'; import type { FctBlockFirstSeenByNode, @@ -137,7 +137,7 @@ export function NodeResourcesPanel({ if (!name) continue; const existing = info.get(name) ?? { cl: '', el: '' }; - if (CONSENSUS_CLIENTS.has(clientType) && !existing.cl) { + if (CONSENSUS_CLIENTS_SET.has(clientType) && !existing.cl) { existing.cl = clientType; } else if (EXECUTION_CLIENTS_SET.has(clientType) && !existing.el) { existing.el = clientType; diff --git a/src/pages/xatu/locally-built-blocks/utils/parse-clients.ts b/src/pages/xatu/locally-built-blocks/utils/parse-clients.ts index 6fbcad3fb..3b8f61052 100644 --- a/src/pages/xatu/locally-built-blocks/utils/parse-clients.ts +++ b/src/pages/xatu/locally-built-blocks/utils/parse-clients.ts @@ -1,12 +1,4 @@ -/** - * Known execution client names - */ -const EXECUTION_CLIENTS = ['geth', 'nethermind', 'besu', 'erigon', 'reth'] as const; - -/** - * Known consensus client names - */ -const CONSENSUS_CLIENTS = ['lighthouse', 'prysm', 'teku', 'nimbus', 'lodestar', 'grandine'] as const; +import { CONSENSUS_CLIENTS, EXECUTION_CLIENTS } from '@/utils/ethereum'; /** * Parse the meta_client_name to extract execution and consensus client names diff --git a/src/utils/ethereum.ts b/src/utils/ethereum.ts index dffc1e465..891deb288 100644 --- a/src/utils/ethereum.ts +++ b/src/utils/ethereum.ts @@ -100,25 +100,25 @@ export function truncateAddress(pubkey?: string, startChars = 6, endChars = 4): /** * Known consensus client names */ -export const CONSENSUS_CLIENTS = new Set(['lighthouse', 'lodestar', 'nimbus', 'prysm', 'teku', 'grandine']); +export const CONSENSUS_CLIENTS = ['lighthouse', 'lodestar', 'nimbus', 'prysm', 'teku', 'grandine'] as const; +export const CONSENSUS_CLIENTS_SET = new Set(CONSENSUS_CLIENTS); /** * Known execution client names */ -export const EXECUTION_CLIENTS_SET = new Set(['besu', 'erigon', 'geth', 'nethermind', 'reth', 'ethrex']); +export const EXECUTION_CLIENTS = ['geth', 'nethermind', 'besu', 'erigon', 'reth', 'ethrex'] as const; +export const EXECUTION_CLIENTS_SET = new Set(EXECUTION_CLIENTS); /** * Determine whether a client type string is a CL or EL client */ export function getClientLayer(clientType: string): 'CL' | 'EL' | null { const lower = clientType.toLowerCase(); - if (CONSENSUS_CLIENTS.has(lower)) return 'CL'; + if (CONSENSUS_CLIENTS_SET.has(lower)) return 'CL'; if (EXECUTION_CLIENTS_SET.has(lower)) return 'EL'; return null; } -const EXECUTION_CLIENTS = ['geth', 'nethermind', 'besu', 'erigon', 'reth', 'ethrex'] as const; - /** * Official brand colors for Ethereum execution clients */ From b83aa141f4383ea65cabe38ee87631f0df8d0bcb Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Thu, 12 Feb 2026 18:11:20 +1000 Subject: [PATCH 7/8] fix(slots): align node resource annotations and CL/EL layer detection --- .../NodeResources/NodeResourcesPanel.tsx | 43 ++++++++++++++----- src/utils/ethereum.test.ts | 34 ++++++++++++++- src/utils/ethereum.ts | 2 + 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx index 605130de7..b7d1e4b73 100644 --- a/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/NodeResourcesPanel.tsx @@ -6,7 +6,7 @@ import { Card } from '@/components/Layout/Card'; import { Checkbox } from '@/components/Forms/Checkbox'; import { ReferenceNodesInfoDialog } from '@/pages/ethereum/execution/timings/components/ReferenceNodesInfoDialog'; import { extractClusterFromNodeName } from '@/constants/eip7870'; -import { CONSENSUS_CLIENTS_SET, EXECUTION_CLIENTS_SET } from '@/utils/ethereum'; +import { CONSENSUS_CLIENTS_SET, EXECUTION_CLIENTS_SET, getClientLayer } from '@/utils/ethereum'; import { intEngineNewPayloadServiceListOptions } from '@/api/@tanstack/react-query.gen'; import type { FctBlockFirstSeenByNode, @@ -26,6 +26,16 @@ import { export type { CpuMetric } from './types'; +function nodeMatches(cpuNodeName: string, eventNodeName: string): boolean { + const short = cpuNodeName.split('/').pop() ?? cpuNodeName; + return ( + eventNodeName === short || + eventNodeName === cpuNodeName || + short.includes(eventNodeName) || + eventNodeName.includes(short) + ); +} + interface NodeResourcesPanelProps { slot: number; blockPropagation: FctBlockFirstSeenByNode[]; @@ -137,9 +147,11 @@ export function NodeResourcesPanel({ if (!name) continue; const existing = info.get(name) ?? { cl: '', el: '' }; - if (CONSENSUS_CLIENTS_SET.has(clientType) && !existing.cl) { + const layer = getClientLayer(clientType); + + if ((CONSENSUS_CLIENTS_SET.has(clientType) || layer === 'CL') && !existing.cl) { existing.cl = clientType; - } else if (EXECUTION_CLIENTS_SET.has(clientType) && !existing.el) { + } else if ((EXECUTION_CLIENTS_SET.has(clientType) || layer === 'EL') && !existing.el) { existing.el = clientType; } info.set(name, existing); @@ -153,22 +165,32 @@ export function NodeResourcesPanel({ // Build raw per-node annotation events (chart handles aggregation) const annotations = useMemo((): AnnotationEvent[] => { const events: AnnotationEvent[] = []; + const filteredNodeSet = new Set(nodeNames); + const isIncludedNode = (nodeName: string): boolean => { + if (filteredNodeSet.has(nodeName)) return true; + for (const filteredNodeName of filteredNodeSet) { + if (nodeMatches(filteredNodeName, nodeName)) return true; + } + return false; + }; for (const p of blockPropagation) { - if (p.node_id) { - events.push({ type: 'block', timeMs: p.seen_slot_start_diff ?? 0, nodeName: p.node_id }); + const nodeName = p.meta_client_name ?? p.node_id; + if (nodeName && isIncludedNode(nodeName)) { + events.push({ type: 'block', timeMs: p.seen_slot_start_diff ?? 0, nodeName }); } } for (const p of headPropagation) { - if (p.node_id) { - events.push({ type: 'head', timeMs: p.seen_slot_start_diff ?? 0, nodeName: p.node_id }); + const nodeName = p.meta_client_name ?? p.node_id; + if (nodeName && isIncludedNode(nodeName)) { + events.push({ type: 'head', timeMs: p.seen_slot_start_diff ?? 0, nodeName }); } } const execItems = executionData?.int_engine_new_payload ?? []; for (const e of execItems) { - if (e.meta_client_name) { + if (e.meta_client_name && isIncludedNode(e.meta_client_name)) { const slotStartMs = (e.slot_start_date_time ?? 0) * 1000; const requestedMs = (e.requested_date_time ?? 0) / 1000; const startMs = requestedMs - slotStartMs; @@ -186,8 +208,9 @@ export function NodeResourcesPanel({ // Data columns: group by node, produce one range event per node const colsByNode = new Map(); for (const c of dataColumnPropagation) { - const nid = c.node_id ?? ''; + const nid = c.meta_client_name ?? c.node_id ?? ''; if (!nid) continue; + if (!isIncludedNode(nid)) continue; if (!colsByNode.has(nid)) colsByNode.set(nid, []); colsByNode.get(nid)!.push(c.seen_slot_start_diff ?? 0); } @@ -204,7 +227,7 @@ export function NodeResourcesPanel({ } return events; - }, [blockPropagation, headPropagation, dataColumnPropagation, executionData]); + }, [blockPropagation, headPropagation, dataColumnPropagation, executionData, nodeNames]); // Which annotation types have data (slot_phases is always available) const availableAnnotations = useMemo(() => { diff --git a/src/utils/ethereum.test.ts b/src/utils/ethereum.test.ts index d761ac706..4a2ffe112 100644 --- a/src/utils/ethereum.test.ts +++ b/src/utils/ethereum.test.ts @@ -1,5 +1,13 @@ import { describe, it, expect } from 'vitest'; -import { weiToEth, ethToWei, weiToGwei, gweiToWei, truncateAddress, parseExecutionClient } from './ethereum'; +import { + weiToEth, + ethToWei, + weiToGwei, + gweiToWei, + truncateAddress, + parseExecutionClient, + getClientLayer, +} from './ethereum'; describe('weiToEth', () => { it('should convert 1 ETH in wei to ETH', () => { @@ -179,3 +187,27 @@ describe('parseExecutionClient', () => { expect(parseExecutionClient('Nethermind / v1.25.4 ')).toBe('Nethermind v1.25.4'); }); }); + +describe('getClientLayer', () => { + it('should classify known consensus clients as CL', () => { + expect(getClientLayer('lighthouse')).toBe('CL'); + expect(getClientLayer('TeKu')).toBe('CL'); + }); + + it('should classify known execution clients as EL', () => { + expect(getClientLayer('geth')).toBe('EL'); + expect(getClientLayer('Nethermind')).toBe('EL'); + }); + + it('should classify CL/EL aliases case-insensitively', () => { + expect(getClientLayer('CL')).toBe('CL'); + expect(getClientLayer('cl')).toBe('CL'); + expect(getClientLayer('EL')).toBe('EL'); + expect(getClientLayer('el')).toBe('EL'); + }); + + it('should return null for unknown client types', () => { + expect(getClientLayer('')).toBeNull(); + expect(getClientLayer('unknown-client')).toBeNull(); + }); +}); diff --git a/src/utils/ethereum.ts b/src/utils/ethereum.ts index 891deb288..3084590bb 100644 --- a/src/utils/ethereum.ts +++ b/src/utils/ethereum.ts @@ -114,6 +114,8 @@ export const EXECUTION_CLIENTS_SET = new Set(EXECUTION_CLIENTS); */ export function getClientLayer(clientType: string): 'CL' | 'EL' | null { const lower = clientType.toLowerCase(); + if (lower === 'cl') return 'CL'; + if (lower === 'el') return 'EL'; if (CONSENSUS_CLIENTS_SET.has(lower)) return 'CL'; if (EXECUTION_CLIENTS_SET.has(lower)) return 'EL'; return null; From 379de6004b718af3216ce87299dd1ac1f2bc31c3 Mon Sep 17 00:00:00 2001 From: Sam Calder-Mason Date: Thu, 12 Feb 2026 19:33:38 +1000 Subject: [PATCH 8/8] =?UTF-8?q?rename:=20fct=5Fnode=5Fcpu=5Futilization=20?= =?UTF-8?q?=E2=86=92=20fct=5Fnode=5Fcpu=5Futilization=5Fby=5Fprocess?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regenerated API types and updated component/hook imports to match the renamed xatu-cbt table. --- src/api/@tanstack/react-query.gen.ts | 58 ++++++++++--------- src/api/index.ts | 30 +++++----- src/api/sdk.gen.ts | 48 +++++++-------- src/api/types.gen.ts | 56 +++++++++--------- src/api/zod.gen.ts | 22 +++---- .../NodeResources/CpuUtilizationChart.tsx | 6 +- .../useSlotNodeResources.ts | 10 ++-- 7 files changed, 118 insertions(+), 112 deletions(-) diff --git a/src/api/@tanstack/react-query.gen.ts b/src/api/@tanstack/react-query.gen.ts index d588ae456..95bdf7996 100644 --- a/src/api/@tanstack/react-query.gen.ts +++ b/src/api/@tanstack/react-query.gen.ts @@ -184,8 +184,8 @@ import { fctMissedSlotRateHourlyServiceList, fctNodeActiveLast24hServiceGet, fctNodeActiveLast24hServiceList, - fctNodeCpuUtilizationServiceGet, - fctNodeCpuUtilizationServiceList, + fctNodeCpuUtilizationByProcessServiceGet, + fctNodeCpuUtilizationByProcessServiceList, fctOpcodeGasByOpcodeDailyServiceGet, fctOpcodeGasByOpcodeDailyServiceList, fctOpcodeGasByOpcodeHourlyServiceGet, @@ -903,12 +903,12 @@ import type { FctNodeActiveLast24hServiceListData, FctNodeActiveLast24hServiceListError, FctNodeActiveLast24hServiceListResponse, - FctNodeCpuUtilizationServiceGetData, - FctNodeCpuUtilizationServiceGetError, - FctNodeCpuUtilizationServiceGetResponse, - FctNodeCpuUtilizationServiceListData, - FctNodeCpuUtilizationServiceListError, - FctNodeCpuUtilizationServiceListResponse, + FctNodeCpuUtilizationByProcessServiceGetData, + FctNodeCpuUtilizationByProcessServiceGetError, + FctNodeCpuUtilizationByProcessServiceGetResponse, + FctNodeCpuUtilizationByProcessServiceListData, + FctNodeCpuUtilizationByProcessServiceListError, + FctNodeCpuUtilizationByProcessServiceListResponse, FctOpcodeGasByOpcodeDailyServiceGetData, FctOpcodeGasByOpcodeDailyServiceGetError, FctOpcodeGasByOpcodeDailyServiceGetResponse, @@ -6683,23 +6683,26 @@ export const fctNodeActiveLast24hServiceGetOptions = (options: Options) => - createQueryKey('fctNodeCpuUtilizationServiceList', options); +export const fctNodeCpuUtilizationByProcessServiceListQueryKey = ( + options?: Options +) => createQueryKey('fctNodeCpuUtilizationByProcessServiceList', options); /** * List records * * Retrieve paginated results with optional filtering */ -export const fctNodeCpuUtilizationServiceListOptions = (options?: Options) => +export const fctNodeCpuUtilizationByProcessServiceListOptions = ( + options?: Options +) => queryOptions< - FctNodeCpuUtilizationServiceListResponse, - FctNodeCpuUtilizationServiceListError, - FctNodeCpuUtilizationServiceListResponse, - ReturnType + FctNodeCpuUtilizationByProcessServiceListResponse, + FctNodeCpuUtilizationByProcessServiceListError, + FctNodeCpuUtilizationByProcessServiceListResponse, + ReturnType >({ queryFn: async ({ queryKey, signal }) => { - const { data } = await fctNodeCpuUtilizationServiceList({ + const { data } = await fctNodeCpuUtilizationByProcessServiceList({ ...options, ...queryKey[0], signal, @@ -6707,26 +6710,29 @@ export const fctNodeCpuUtilizationServiceListOptions = (options?: Options) => - createQueryKey('fctNodeCpuUtilizationServiceGet', options); +export const fctNodeCpuUtilizationByProcessServiceGetQueryKey = ( + options: Options +) => createQueryKey('fctNodeCpuUtilizationByProcessServiceGet', options); /** * Get record * * Retrieve a single record by wallclock_slot_start_date_time */ -export const fctNodeCpuUtilizationServiceGetOptions = (options: Options) => +export const fctNodeCpuUtilizationByProcessServiceGetOptions = ( + options: Options +) => queryOptions< - FctNodeCpuUtilizationServiceGetResponse, - FctNodeCpuUtilizationServiceGetError, - FctNodeCpuUtilizationServiceGetResponse, - ReturnType + FctNodeCpuUtilizationByProcessServiceGetResponse, + FctNodeCpuUtilizationByProcessServiceGetError, + FctNodeCpuUtilizationByProcessServiceGetResponse, + ReturnType >({ queryFn: async ({ queryKey, signal }) => { - const { data } = await fctNodeCpuUtilizationServiceGet({ + const { data } = await fctNodeCpuUtilizationByProcessServiceGet({ ...options, ...queryKey[0], signal, @@ -6734,7 +6740,7 @@ export const fctNodeCpuUtilizationServiceGetOptions = (options: Options( - options?: Options +export const fctNodeCpuUtilizationByProcessServiceList = ( + options?: Options ) => (options?.client ?? client).get< - FctNodeCpuUtilizationServiceListResponses, - FctNodeCpuUtilizationServiceListErrors, + FctNodeCpuUtilizationByProcessServiceListResponses, + FctNodeCpuUtilizationByProcessServiceListErrors, ThrowOnError >({ - requestValidator: async data => await zFctNodeCpuUtilizationServiceListData.parseAsync(data), - responseValidator: async data => await zFctNodeCpuUtilizationServiceListResponse.parseAsync(data), - url: '/api/v1/fct_node_cpu_utilization', + requestValidator: async data => await zFctNodeCpuUtilizationByProcessServiceListData.parseAsync(data), + responseValidator: async data => await zFctNodeCpuUtilizationByProcessServiceListResponse.parseAsync(data), + url: '/api/v1/fct_node_cpu_utilization_by_process', ...options, }); @@ -5226,17 +5226,17 @@ export const fctNodeCpuUtilizationServiceList = ( - options: Options +export const fctNodeCpuUtilizationByProcessServiceGet = ( + options: Options ) => (options.client ?? client).get< - FctNodeCpuUtilizationServiceGetResponses, - FctNodeCpuUtilizationServiceGetErrors, + FctNodeCpuUtilizationByProcessServiceGetResponses, + FctNodeCpuUtilizationByProcessServiceGetErrors, ThrowOnError >({ - requestValidator: async data => await zFctNodeCpuUtilizationServiceGetData.parseAsync(data), - responseValidator: async data => await zFctNodeCpuUtilizationServiceGetResponse.parseAsync(data), - url: '/api/v1/fct_node_cpu_utilization/{wallclock_slot_start_date_time}', + requestValidator: async data => await zFctNodeCpuUtilizationByProcessServiceGetData.parseAsync(data), + responseValidator: async data => await zFctNodeCpuUtilizationByProcessServiceGetResponse.parseAsync(data), + url: '/api/v1/fct_node_cpu_utilization_by_process/{wallclock_slot_start_date_time}', ...options, }); diff --git a/src/api/types.gen.ts b/src/api/types.gen.ts index f2a4b6bb9..3cdab65f7 100644 --- a/src/api/types.gen.ts +++ b/src/api/types.gen.ts @@ -4560,7 +4560,7 @@ export type FctNodeActiveLast24h = { username?: string; }; -export type FctNodeCpuUtilization = { +export type FctNodeCpuUtilizationByProcess = { /** * Client type: CL or EL */ @@ -6205,10 +6205,10 @@ export type GetFctNodeActiveLast24hResponse = { }; /** - * Response for getting a single fct_node_cpu_utilization record + * Response for getting a single fct_node_cpu_utilization_by_process record */ -export type GetFctNodeCpuUtilizationResponse = { - item?: FctNodeCpuUtilization; +export type GetFctNodeCpuUtilizationByProcessResponse = { + item?: FctNodeCpuUtilizationByProcess; }; /** @@ -10702,13 +10702,13 @@ export type ListFctNodeActiveLast24hResponse = { }; /** - * Response for listing fct_node_cpu_utilization records + * Response for listing fct_node_cpu_utilization_by_process records */ -export type ListFctNodeCpuUtilizationResponse = { +export type ListFctNodeCpuUtilizationByProcessResponse = { /** - * The list of fct_node_cpu_utilization. + * The list of fct_node_cpu_utilization_by_process. */ - fct_node_cpu_utilization?: Array; + fct_node_cpu_utilization_by_process?: Array; /** * A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. */ @@ -55101,7 +55101,7 @@ export type FctNodeActiveLast24hServiceGetResponses = { export type FctNodeActiveLast24hServiceGetResponse = FctNodeActiveLast24hServiceGetResponses[keyof FctNodeActiveLast24hServiceGetResponses]; -export type FctNodeCpuUtilizationServiceListData = { +export type FctNodeCpuUtilizationByProcessServiceListData = { body?: never; path?: never; query?: { @@ -55502,11 +55502,11 @@ export type FctNodeCpuUtilizationServiceListData = { */ node_class_not_in_values?: string; /** - * The maximum number of fct_node_cpu_utilization to return. If unspecified, at most 100 items will be returned. The maximum value is 10000; values above 10000 will be coerced to 10000. + * The maximum number of fct_node_cpu_utilization_by_process to return. If unspecified, at most 100 items will be returned. The maximum value is 10000; values above 10000 will be coerced to 10000. */ page_size?: number; /** - * A page token, received from a previous `ListFctNodeCpuUtilization` call. Provide this to retrieve the subsequent page. + * A page token, received from a previous `ListFctNodeCpuUtilizationByProcess` call. Provide this to retrieve the subsequent page. */ page_token?: string; /** @@ -55514,30 +55514,30 @@ export type FctNodeCpuUtilizationServiceListData = { */ order_by?: string; }; - url: '/api/v1/fct_node_cpu_utilization'; + url: '/api/v1/fct_node_cpu_utilization_by_process'; }; -export type FctNodeCpuUtilizationServiceListErrors = { +export type FctNodeCpuUtilizationByProcessServiceListErrors = { /** * Default error response */ default: Status; }; -export type FctNodeCpuUtilizationServiceListError = - FctNodeCpuUtilizationServiceListErrors[keyof FctNodeCpuUtilizationServiceListErrors]; +export type FctNodeCpuUtilizationByProcessServiceListError = + FctNodeCpuUtilizationByProcessServiceListErrors[keyof FctNodeCpuUtilizationByProcessServiceListErrors]; -export type FctNodeCpuUtilizationServiceListResponses = { +export type FctNodeCpuUtilizationByProcessServiceListResponses = { /** * OK */ - 200: ListFctNodeCpuUtilizationResponse; + 200: ListFctNodeCpuUtilizationByProcessResponse; }; -export type FctNodeCpuUtilizationServiceListResponse = - FctNodeCpuUtilizationServiceListResponses[keyof FctNodeCpuUtilizationServiceListResponses]; +export type FctNodeCpuUtilizationByProcessServiceListResponse = + FctNodeCpuUtilizationByProcessServiceListResponses[keyof FctNodeCpuUtilizationByProcessServiceListResponses]; -export type FctNodeCpuUtilizationServiceGetData = { +export type FctNodeCpuUtilizationByProcessServiceGetData = { body?: never; path: { /** @@ -55546,28 +55546,28 @@ export type FctNodeCpuUtilizationServiceGetData = { wallclock_slot_start_date_time: number; }; query?: never; - url: '/api/v1/fct_node_cpu_utilization/{wallclock_slot_start_date_time}'; + url: '/api/v1/fct_node_cpu_utilization_by_process/{wallclock_slot_start_date_time}'; }; -export type FctNodeCpuUtilizationServiceGetErrors = { +export type FctNodeCpuUtilizationByProcessServiceGetErrors = { /** * Default error response */ default: Status; }; -export type FctNodeCpuUtilizationServiceGetError = - FctNodeCpuUtilizationServiceGetErrors[keyof FctNodeCpuUtilizationServiceGetErrors]; +export type FctNodeCpuUtilizationByProcessServiceGetError = + FctNodeCpuUtilizationByProcessServiceGetErrors[keyof FctNodeCpuUtilizationByProcessServiceGetErrors]; -export type FctNodeCpuUtilizationServiceGetResponses = { +export type FctNodeCpuUtilizationByProcessServiceGetResponses = { /** * OK */ - 200: GetFctNodeCpuUtilizationResponse; + 200: GetFctNodeCpuUtilizationByProcessResponse; }; -export type FctNodeCpuUtilizationServiceGetResponse = - FctNodeCpuUtilizationServiceGetResponses[keyof FctNodeCpuUtilizationServiceGetResponses]; +export type FctNodeCpuUtilizationByProcessServiceGetResponse = + FctNodeCpuUtilizationByProcessServiceGetResponses[keyof FctNodeCpuUtilizationByProcessServiceGetResponses]; export type FctOpcodeGasByOpcodeDailyServiceListData = { body?: never; diff --git a/src/api/zod.gen.ts b/src/api/zod.gen.ts index 04009bf32..967e48d38 100644 --- a/src/api/zod.gen.ts +++ b/src/api/zod.gen.ts @@ -6631,7 +6631,7 @@ export const zFctNodeActiveLast24h = z.object({ username: z.optional(z.string()), }); -export const zFctNodeCpuUtilization = z.object({ +export const zFctNodeCpuUtilizationByProcess = z.object({ client_type: z.optional(z.string()), max_core_pct: z.optional(z.number()), mean_core_pct: z.optional(z.number()), @@ -8649,10 +8649,10 @@ export const zGetFctNodeActiveLast24hResponse = z.object({ }); /** - * Response for getting a single fct_node_cpu_utilization record + * Response for getting a single fct_node_cpu_utilization_by_process record */ -export const zGetFctNodeCpuUtilizationResponse = z.object({ - item: z.optional(zFctNodeCpuUtilization), +export const zGetFctNodeCpuUtilizationByProcessResponse = z.object({ + item: z.optional(zFctNodeCpuUtilizationByProcess), }); /** @@ -13806,10 +13806,10 @@ export const zListFctNodeActiveLast24hResponse = z.object({ }); /** - * Response for listing fct_node_cpu_utilization records + * Response for listing fct_node_cpu_utilization_by_process records */ -export const zListFctNodeCpuUtilizationResponse = z.object({ - fct_node_cpu_utilization: z.optional(z.array(zFctNodeCpuUtilization)), +export const zListFctNodeCpuUtilizationByProcessResponse = z.object({ + fct_node_cpu_utilization_by_process: z.optional(z.array(zFctNodeCpuUtilizationByProcess)), next_page_token: z.optional(z.string()), }); @@ -68966,7 +68966,7 @@ export const zFctNodeActiveLast24hServiceGetData = z.object({ */ export const zFctNodeActiveLast24hServiceGetResponse = zGetFctNodeActiveLast24hResponse; -export const zFctNodeCpuUtilizationServiceListData = z.object({ +export const zFctNodeCpuUtilizationByProcessServiceListData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.optional( @@ -69487,9 +69487,9 @@ export const zFctNodeCpuUtilizationServiceListData = z.object({ /** * OK */ -export const zFctNodeCpuUtilizationServiceListResponse = zListFctNodeCpuUtilizationResponse; +export const zFctNodeCpuUtilizationByProcessServiceListResponse = zListFctNodeCpuUtilizationByProcessResponse; -export const zFctNodeCpuUtilizationServiceGetData = z.object({ +export const zFctNodeCpuUtilizationByProcessServiceGetData = z.object({ body: z.optional(z.never()), path: z.object({ wallclock_slot_start_date_time: z.coerce @@ -69509,7 +69509,7 @@ export const zFctNodeCpuUtilizationServiceGetData = z.object({ /** * OK */ -export const zFctNodeCpuUtilizationServiceGetResponse = zGetFctNodeCpuUtilizationResponse; +export const zFctNodeCpuUtilizationByProcessServiceGetResponse = zGetFctNodeCpuUtilizationByProcessResponse; export const zFctOpcodeGasByOpcodeDailyServiceListData = z.object({ body: z.optional(z.never()), diff --git a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx index 2702b9549..b46eeb081 100644 --- a/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx +++ b/src/pages/ethereum/slots/components/NodeResources/CpuUtilizationChart.tsx @@ -6,7 +6,7 @@ import { getDataVizColors, getClientLayer } from '@/utils'; import { DEFAULT_BEACON_SLOT_PHASES } from '@/utils/beacon'; import { ClientLogo } from '@/components/Ethereum/ClientLogo'; import { SelectMenu } from '@/components/Forms/SelectMenu'; -import type { FctNodeCpuUtilization } from '@/api/types.gen'; +import type { FctNodeCpuUtilizationByProcess } from '@/api/types.gen'; import { ANNOTATION_COLORS, type CpuMetric, type AnnotationType, type AnnotationEvent } from './types'; function usToSeconds(us: number): number { @@ -56,7 +56,7 @@ interface BucketAgg { } interface CpuUtilizationChartProps { - data: FctNodeCpuUtilization[]; + data: FctNodeCpuUtilizationByProcess[]; selectedNode: string | null; metric: CpuMetric; onMetricChange: (metric: CpuMetric) => void; @@ -100,7 +100,7 @@ export function CpuUtilizationChart({ let resolvedClClient = ''; let resolvedElClient = ''; - const bucketData = (items: FctNodeCpuUtilization[]): Map => { + const bucketData = (items: FctNodeCpuUtilizationByProcess[]): Map => { const buckets = new Map(); for (const d of items) { const offset = usToSeconds((d.window_start ?? 0) - slotStartUs); diff --git a/src/pages/ethereum/slots/hooks/useSlotNodeResources/useSlotNodeResources.ts b/src/pages/ethereum/slots/hooks/useSlotNodeResources/useSlotNodeResources.ts index d810d84dc..ed3a14ef1 100644 --- a/src/pages/ethereum/slots/hooks/useSlotNodeResources/useSlotNodeResources.ts +++ b/src/pages/ethereum/slots/hooks/useSlotNodeResources/useSlotNodeResources.ts @@ -1,14 +1,14 @@ import { useQuery } from '@tanstack/react-query'; -import { fctNodeCpuUtilizationServiceListOptions } from '@/api/@tanstack/react-query.gen'; +import { fctNodeCpuUtilizationByProcessServiceListOptions } from '@/api/@tanstack/react-query.gen'; import { useNetwork } from '@/hooks/useNetwork'; import { slotToTimestamp } from '@/utils/beacon'; -import type { FctNodeCpuUtilization } from '@/api/types.gen'; +import type { FctNodeCpuUtilizationByProcess } from '@/api/types.gen'; /** cbt-api returns DateTime64(3) fields as microseconds */ const SECONDS_TO_MICROSECONDS = 1_000_000; export interface UseSlotNodeResourcesResult { - data: FctNodeCpuUtilization[] | null; + data: FctNodeCpuUtilizationByProcess[] | null; isLoading: boolean; error: Error | null; } @@ -19,7 +19,7 @@ export function useSlotNodeResources(slot: number): UseSlotNodeResourcesResult { const slotTimestampUs = slotTimestamp * SECONDS_TO_MICROSECONDS; const { data, isLoading, error } = useQuery({ - ...fctNodeCpuUtilizationServiceListOptions({ + ...fctNodeCpuUtilizationByProcessServiceListOptions({ query: { wallclock_slot_start_date_time_eq: slotTimestampUs, page_size: 10000, @@ -28,7 +28,7 @@ export function useSlotNodeResources(slot: number): UseSlotNodeResourcesResult { enabled: !!currentNetwork && slotTimestamp > 0, }); - const cpuData = data?.fct_node_cpu_utilization ?? null; + const cpuData = data?.fct_node_cpu_utilization_by_process ?? null; return { data: cpuData,