feat: add getLeaderSchedule api

This commit is contained in:
Justin Starry
2020-07-17 23:16:44 +08:00
committed by Justin Starry
parent 74b4830ba6
commit d0e139ffff
5 changed files with 74 additions and 0 deletions

View File

@ -6,6 +6,7 @@ declare module 'superstruct' {
literal(schema: any): any;
tuple(schema: any): any;
pick(schema: any): any;
record(schema: any): any;
};
declare module.exports: {

5
web3.js/module.d.ts vendored
View File

@ -193,6 +193,10 @@ declare module '@solana/web3.js' {
firstNormalSlot: number;
};
export type LeaderSchedule = {
[address: string]: number[];
};
export type Supply = {
total: number;
circulating: number;
@ -266,6 +270,7 @@ declare module '@solana/web3.js' {
getTotalSupply(commitment?: Commitment): Promise<number>;
getVersion(): Promise<Version>;
getInflationGovernor(commitment?: Commitment): Promise<InflationGovernor>;
getLeaderSchedule(): Promise<LeaderSchedule>;
getEpochSchedule(): Promise<EpochSchedule>;
getEpochInfo(commitment?: Commitment): Promise<EpochInfo>;
getRecentBlockhashAndContext(

View File

@ -210,6 +210,10 @@ declare module '@solana/web3.js' {
absoluteSlot: number,
};
declare export type LeaderSchedule = {
[address: string]: number[],
};
declare export type Supply = {
total: number,
circulating: number,
@ -283,6 +287,7 @@ declare module '@solana/web3.js' {
getTotalSupply(commitment: ?Commitment): Promise<number>;
getVersion(): Promise<Version>;
getInflationGovernor(commitment: ?Commitment): Promise<InflationGovernor>;
getLeaderSchedule(): Promise<LeaderSchedule>;
getEpochSchedule(): Promise<EpochSchedule>;
getEpochInfo(commitment: ?Commitment): Promise<EpochInfo>;
getRecentBlockhashAndContext(

View File

@ -288,6 +288,21 @@ const GetEpochScheduleResult = struct({
firstNormalSlot: 'number',
});
/**
* Leader schedule
* (see https://docs.solana.com/terminology#leader-schedule)
*
* @typedef {Object} LeaderSchedule
*/
type LeaderSchedule = {
[address: string]: number[],
};
const GetLeaderScheduleResult = struct.record([
'string',
struct.array(['number']),
]);
/**
* Transaction error or null
*/
@ -424,6 +439,13 @@ const GetEpochScheduleRpcResult = struct({
result: GetEpochScheduleResult,
});
/**
* Expected JSON RPC response for the "getLeaderSchedule" message
*/
const GetLeaderScheduleRpcResult = jsonRpcResult(
GetLeaderScheduleResult,
);
/**
* Expected JSON RPC response for the "getBalance" message
*/
@ -1476,6 +1498,20 @@ export class Connection {
return GetEpochScheduleResult(res.result);
}
/**
* Fetch the leader schedule for the current epoch
* @return {Promise<RpcResponseAndContext<LeaderSchedule>>}
*/
async getLeaderSchedule(): Promise<LeaderSchedule> {
const unsafeRes = await this._rpcRequest('getLeaderSchedule', []);
const res = GetLeaderScheduleRpcResult(unsafeRes);
if (res.error) {
throw new Error('failed to get leader schedule: ' + res.error.message);
}
assert(typeof res.result !== 'undefined');
return res.result;
}
/**
* Fetch the minimum balance needed to exempt an account of `dataLength`
* size from rent

View File

@ -443,6 +443,33 @@ test('get epoch schedule', async () => {
}
});
test('get leader schedule', async () => {
const connection = new Connection(url);
mockRpc.push([
url,
{
method: 'getLeaderSchedule',
params: [],
},
{
error: null,
result: {
'123vij84ecQEKUvQ7gYMKxKwKF6PbYSzCzzURYA4xULY': [0, 1, 2, 3],
'8PTjAikKoAybKXcEPnDSoy8wSNNikUBJ1iKawJKQwXnB': [4, 5, 6, 7],
},
},
]);
const leaderSchedule = await connection.getLeaderSchedule();
expect(Object.keys(leaderSchedule).length).toBeGreaterThanOrEqual(1);
for (const key in leaderSchedule) {
const slots = leaderSchedule[key];
expect(Array.isArray(slots)).toBe(true);
expect(slots.length).toBeGreaterThanOrEqual(4);
}
});
test('get slot', async () => {
const connection = new Connection(url);