Skip to content

Commit

Permalink
refactor(experimental): fix a few RPC methods
Browse files Browse the repository at this point in the history
This change simply fixes a handful of incorrect RPC method signatures, as per
the RPC docs.

Stems from errors found in #2087.
  • Loading branch information
buffalojoec committed Feb 19, 2024
1 parent db105a6 commit bb65ba9
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('getLeaderSchedule', () => {
describe('when called with no identity and no slot', () => {
it('returns the leader schedule for all cluster nodes in the current epoch', async () => {
expect.assertions(3);
const res = await rpc.getLeaderSchedule({ commitment }).send();
const res = await rpc.getLeaderSchedule(null, { commitment }).send();
// Does not need null check (default slot)
expect(res).toStrictEqual(expect.any(Object));
for (const key of Object.keys(res)) {
Expand Down Expand Up @@ -79,7 +79,7 @@ describe('getLeaderSchedule', () => {
expect.assertions(1);
const identity = await getValidatorAddress();
const res = await rpc
.getLeaderSchedule({
.getLeaderSchedule(null, {
commitment,
identity,
})
Expand Down Expand Up @@ -114,7 +114,7 @@ describe('getLeaderSchedule', () => {
it('returns an empty object', async () => {
expect.assertions(1);
const res = await rpc
.getLeaderSchedule({
.getLeaderSchedule(null, {
commitment,
// See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json
identity: 'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address,
Expand All @@ -128,7 +128,7 @@ describe('getLeaderSchedule', () => {
it('returns an empty object', async () => {
expect.assertions(1);
const res = await rpc
.getLeaderSchedule({
.getLeaderSchedule(null, {
commitment,
// Randomly generated
identity: 'BnWCFuxmi6uH3ceVx4R8qcbWBMPVVYVVFWtAiiTA1PAu' as Address,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Address } from '@solana/addresses';
import { Rpc, Slot } from '@solana/rpc-types';

import { GetLeaderScheduleApi } from '../getLeaderSchedule';

const rpc = null as unknown as Rpc<GetLeaderScheduleApi>;
const slot = 0n as Slot;
const identity = 'Joe11111111111111111111111111111' as Address<'Joe11111111111111111111111111111'>;

async () => {
{
const result = await rpc.getLeaderSchedule(slot).send();
// Can be null if the slot corresponds to an epoch that does not exist
result satisfies Record<Address, Slot[]> | null;
}

{
const result = await rpc.getLeaderSchedule(null).send();
// Won't be null
result satisfies Record<Address, Slot[]>;
}

{
const result = await rpc.getLeaderSchedule(slot, { identity }).send();
// Can be null if the slot corresponds to an epoch that does not exist
result satisfies Readonly<{ [key: Address]: Slot[] | undefined }> | null;
}

{
const result = await rpc.getLeaderSchedule(null, { identity }).send();
// Won't be null
result satisfies Readonly<{ [key: Address]: Slot[] | undefined }>;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Address } from '@solana/addresses';
import { Rpc } from '@solana/rpc-types';

import { GetSupplyApi } from '../getSupply';

const rpc = null as unknown as Rpc<GetSupplyApi>;

async () => {
{
const result = await rpc.getSupply({ excludeNonCirculatingAccountsList: true }).send();
result satisfies Readonly<{
value: Readonly<{
nonCirculatingAccounts: never[];
}>;
}>;
}

{
const result = await rpc.getSupply().send();
result satisfies Readonly<{
value: Readonly<{
nonCirculatingAccounts: Address[];
}>;
}>;
// @ts-expect-error should not be `never`
result satisfies Readonly<{
value: Readonly<{
nonCirculatingAccounts: never[];
}>;
}>;
}

{
const result = await rpc.getSupply({ excludeNonCirculatingAccountsList: false }).send();
result satisfies Readonly<{
value: Readonly<{
nonCirculatingAccounts: Address[];
}>;
}>;
// @ts-expect-error should not be `never`
result satisfies Readonly<{
value: Readonly<{
nonCirculatingAccounts: never[];
}>;
}>;
}
};
50 changes: 34 additions & 16 deletions packages/rpc-core/src/rpc-methods/getLeaderSchedule.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { Address } from '@solana/addresses';
import type { Commitment, IRpcApiMethods, Slot } from '@solana/rpc-types';

type GetLeaderScheduleApiConfigBase = Readonly<{
commitment?: Commitment;
}>;

/**
* This return type is a dictionary of validator identities, as base-58 encoded
* strings, and their corresponding leader slot indices as values
Expand All @@ -17,8 +21,10 @@ import type { Commitment, IRpcApiMethods, Slot } from '@solana/rpc-types';
* }
* ```
*/
type GetLeaderScheduleApiResponseBase = Readonly<{
[key: Address]: Slot[];
type GetLeaderScheduleApiResponseWithAllIdentities = Record<Address, Slot[]>;

type GetLeaderScheduleApiResponseWithSingleIdentity<TIdentity extends string> = Readonly<{
[TAddress in TIdentity]?: Slot[];
}>;

export interface GetLeaderScheduleApi extends IRpcApiMethods {
Expand All @@ -28,21 +34,33 @@ export interface GetLeaderScheduleApi extends IRpcApiMethods {
*
* When a slot is provided, the leader schedule for the epoch that corresponds
* to the provided slot is returned, and this can be null if the slot corresponds
* to an epoch that does not exist
* to an epoch that does not exist.
*
* The RPC request payload provides a `null` value for `slot` when the slot is not
* specified but the request wishes to include config.
*/
getLeaderSchedule<TIdentity extends Address>(
slot: Slot,
config: GetLeaderScheduleApiConfigBase &
Readonly<{
/** Only return results for this validator identity (base58 encoded address) */
identity: Address;
}>,
): GetLeaderScheduleApiResponseWithSingleIdentity<TIdentity> | null;
getLeaderSchedule(
slot: Slot,
config?: Readonly<{
commitment?: Commitment;
/** Only return results for this validator identity (base58 encoded address) */
identity?: Address;
}>,
): GetLeaderScheduleApiResponseBase | null;
config?: GetLeaderScheduleApiConfigBase,
): GetLeaderScheduleApiResponseWithAllIdentities | null;
getLeaderSchedule<TIdentity extends Address>(
slot: null,
config: GetLeaderScheduleApiConfigBase &
Readonly<{
/** Only return results for this validator identity (base58 encoded address) */
identity: Address;
}>,
): GetLeaderScheduleApiResponseWithSingleIdentity<TIdentity>;
getLeaderSchedule(
config?: Readonly<{
commitment?: Commitment;
/** Only return results for this validator identity (base58 encoded address) */
identity?: Address;
}>,
): GetLeaderScheduleApiResponseBase;
}
slot: null,
config?: GetLeaderScheduleApiConfigBase,
): GetLeaderScheduleApiResponseWithAllIdentities;
}
18 changes: 13 additions & 5 deletions packages/rpc-core/src/rpc-methods/getSupply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { Commitment, IRpcApiMethods, LamportsUnsafeBeyond2Pow53Minus1, RpcR

type GetSupplyConfig = Readonly<{
commitment?: Commitment;
excludeNonCirculatingAccountsList?: boolean;
}>;

type GetSupplyApiResponseBase = RpcResponse<{
Expand All @@ -19,14 +18,18 @@ type GetSupplyApiResponseWithNonCirculatingAccounts = GetSupplyApiResponseBase &
Readonly<{
value: Readonly<{
/** an array of account addresses of non-circulating accounts */
nonCirculatingAccounts: [Address];
nonCirculatingAccounts: Address[];
}>;
}>;

type GetSupplyApiResponseWithoutNonCirculatingAccounts = GetSupplyApiResponseBase &
Readonly<{
value: Readonly<{
nonCirculatingAccounts: [];
/** As per the docs:
* "If `excludeNonCirculatingAccountsList` is enabled, the returned array will be empty."
* See: https://solana.com/docs/rpc/http/getsupply
*/
nonCirculatingAccounts: never[];
}>;
}>;

Expand All @@ -40,5 +43,10 @@ export interface GetSupplyApi extends IRpcApiMethods {
excludeNonCirculatingAccountsList: true;
}>,
): GetSupplyApiResponseWithoutNonCirculatingAccounts;
getSupply(config?: GetSupplyConfig): GetSupplyApiResponseWithNonCirculatingAccounts;
}
getSupply(
config?: GetSupplyConfig &
Readonly<{
excludeNonCirculatingAccountsList?: false;
}>,
): GetSupplyApiResponseWithNonCirculatingAccounts;
}

0 comments on commit bb65ba9

Please sign in to comment.