From 2c5352cb671b55203e5886f087c219ed7ed0f875 Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Fri, 21 Apr 2023 13:21:41 +0000 Subject: [PATCH] fixup! refactor(experimental): add `getBlockProduction` API --- .../__tests__/get-block-production-test.ts | 28 +++++++------- .../src/rpc-methods/getBlockProduction.ts | 37 ++++++++++++++----- pnpm-lock.yaml | 2 +- 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/packages/rpc-core/src/rpc-methods/__tests__/get-block-production-test.ts b/packages/rpc-core/src/rpc-methods/__tests__/get-block-production-test.ts index 39ae80928ba8..533e37a83517 100644 --- a/packages/rpc-core/src/rpc-methods/__tests__/get-block-production-test.ts +++ b/packages/rpc-core/src/rpc-methods/__tests__/get-block-production-test.ts @@ -1,19 +1,19 @@ -import { createJsonRpcTransport } from '@solana/rpc-transport'; -import type { SolanaJsonRpcErrorCode } from '@solana/rpc-transport/dist/types/json-rpc-transport/json-rpc-errors'; -import type { Transport } from '@solana/rpc-transport/dist/types/json-rpc-transport/json-rpc-transport-types'; +import { createHttpTransport, createJsonRpc } from '@solana/rpc-transport'; +import type { SolanaJsonRpcErrorCode } from '@solana/rpc-transport/dist/types/json-rpc-errors'; +import type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types'; import fetchMock from 'jest-fetch-mock-fork'; import { createSolanaRpcApi, SolanaRpcMethods } from '../../index'; import { Commitment } from '../common'; import { Base58EncodedAddress } from '@solana/keys'; -describe('getBalance', () => { - let transport: Transport; +describe('getBlockProduction', () => { + let rpc: Rpc; beforeEach(() => { fetchMock.resetMocks(); fetchMock.dontMock(); - transport = createJsonRpcTransport({ + rpc = createJsonRpc({ api: createSolanaRpcApi(), - url: 'http://127.0.0.1:8899', + transport: createHttpTransport({ url: 'http://127.0.0.1:8899' }), }); }); @@ -21,7 +21,7 @@ describe('getBalance', () => { describe(`when called with \`${commitment}\` commitment`, () => { it('returns block production data', async () => { expect.assertions(1); - const blockProductionPromise = transport.getBlockProduction({ commitment }).send(); + const blockProductionPromise = rpc.getBlockProduction({ commitment }).send(); await expect(blockProductionPromise).resolves.toMatchObject({ value: expect.objectContaining({ byIdentity: expect.toBeObject(), @@ -35,10 +35,8 @@ describe('getBalance', () => { it('has the latest context slot as the last slot', async () => { expect.assertions(1); - const blockProductionPromise = transport.getBlockProduction({ commitment }).send(); - await expect(blockProductionPromise).resolves.toSatisfy( - rpcResponse => rpcResponse.context.slot === rpcResponse.value.range.lastSlot - ); + const blockProduction = await rpc.getBlockProduction({ commitment }).send(); + expect(blockProduction.value.range.lastSlot).toBe(blockProduction.context.slot); }); }); }); @@ -51,7 +49,7 @@ describe('getBalance', () => { expect.assertions(1); // Randomly generated address, assumed not to be a block producer const identity = '9NmqDDZa7mH1DBM4zeq9cm7VcRn2un1i2TwuMvjBoVhU' as Base58EncodedAddress; - const blockProductionPromise = transport.getBlockProduction({ identity }).send(); + const blockProductionPromise = rpc.getBlockProduction({ identity }).send(); await expect(blockProductionPromise).resolves.toMatchObject({ value: expect.objectContaining({ byIdentity: expect.toBeEmptyObject(), @@ -63,7 +61,7 @@ describe('getBalance', () => { describe('when called with a `lastSlot` higher than the highest slot available', () => { it('throws an error', async () => { expect.assertions(1); - const blockProductionPromise = transport + const blockProductionPromise = rpc .getBlockProduction({ range: { firstSlot: 0n, @@ -72,7 +70,7 @@ describe('getBalance', () => { }) .send(); await expect(blockProductionPromise).rejects.toMatchObject({ - code: -32602 satisfies (typeof SolanaJsonRpcErrorCode)['JSON_RPC_SERVER_ERROR_LAST_SLOT_TOO_LARGE'], + code: -32602 satisfies (typeof SolanaJsonRpcErrorCode)['JSON_RPC_INVALID_PARAMS'], message: expect.any(String), name: 'SolanaJsonRpcError', }); diff --git a/packages/rpc-core/src/rpc-methods/getBlockProduction.ts b/packages/rpc-core/src/rpc-methods/getBlockProduction.ts index 8216ff69d046..56f5044befc4 100644 --- a/packages/rpc-core/src/rpc-methods/getBlockProduction.ts +++ b/packages/rpc-core/src/rpc-methods/getBlockProduction.ts @@ -1,30 +1,47 @@ import { Base58EncodedAddress } from '@solana/keys'; import { Commitment, RpcResponse, U64UnsafeBeyond2Pow53Minus1 } from './common'; -type NumberOfLeaderSlots = number; -type NumberOfBlocksProduced = number; +type NumberOfLeaderSlots = U64UnsafeBeyond2Pow53Minus1; +type NumberOfBlocksProduced = U64UnsafeBeyond2Pow53Minus1; -type Range = Readonly<{ +type SlotRange = Readonly<{ firstSlot: U64UnsafeBeyond2Pow53Minus1; lastSlot: U64UnsafeBeyond2Pow53Minus1; }>; -type GetBlockProductionApiResponse = RpcResponse<{ - byIdentity: Readonly<{ - [address: string]: [NumberOfLeaderSlots, NumberOfBlocksProduced]; +type GetBlockProductionApiResponseBase = RpcResponse<{ + range: SlotRange; +}>; + +type GetBlockProductionApiResponseWithAllIdentities = Readonly<{ + value: Readonly<{ + byIdentity: Record; + }>; +}>; + +type GetBlockProductionApiResponseWithSingleIdentity = Readonly<{ + value: Readonly<{ + byIdentity: { [TAddress in TIdentity]?: [NumberOfLeaderSlots, NumberOfBlocksProduced] }; }>; - range: Range; }>; export interface GetBlockProductionApi { /** * Returns recent block production information from the current or previous epoch. */ + getBlockProduction( + config: Readonly<{ + commitment?: Commitment; + identity: Base58EncodedAddress; + range?: SlotRange; + }> + ): GetBlockProductionApiResponseBase & GetBlockProductionApiResponseWithSingleIdentity; + getBlockProduction( config?: Readonly<{ commitment?: Commitment; - identity?: Base58EncodedAddress; - range?: Range; + identity: undefined; + range?: SlotRange; }> - ): GetBlockProductionApiResponse; + ): GetBlockProductionApiResponseBase & GetBlockProductionApiResponseWithAllIdentities; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d911fdd9c0c4..9d94717e11d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7121,7 +7121,7 @@ packages: jest: optional: true dependencies: - jest: 29.5.0(@types/node@18.15.11)(ts-node@10.9.1) + jest: 29.5.0(@types/node@18.15.12)(ts-node@10.9.1) jest-diff: 29.5.0 jest-get-type: 29.4.3 dev: true