feat: get_epoch_schedule rpc (#536)
This commit is contained in:
		
				
					committed by
					
						
						Michael Vines
					
				
			
			
				
	
			
			
			
						parent
						
							0d582c180f
						
					
				
				
					commit
					67c9b50249
				
			@@ -86,6 +86,23 @@ declare module '@solana/web3.js' {
 | 
				
			|||||||
    Err: Object,
 | 
					    Err: Object,
 | 
				
			||||||
  |};
 | 
					  |};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare export type Inflation = {
 | 
				
			||||||
 | 
					    foundation: number,
 | 
				
			||||||
 | 
					    foundation_term: number,
 | 
				
			||||||
 | 
					    initial: number,
 | 
				
			||||||
 | 
					    storage: number,
 | 
				
			||||||
 | 
					    taper: number,
 | 
				
			||||||
 | 
					    terminal: number,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  declare export type EpochSchedule = {
 | 
				
			||||||
 | 
					    slots_per_epoch: number,
 | 
				
			||||||
 | 
					    leader_schedule_slot_offset: number,
 | 
				
			||||||
 | 
					    warmup: boolean,
 | 
				
			||||||
 | 
					    first_normal_epoch: number,
 | 
				
			||||||
 | 
					    first_normal_slot: number,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  declare export class Connection {
 | 
					  declare export class Connection {
 | 
				
			||||||
    constructor(endpoint: string): Connection;
 | 
					    constructor(endpoint: string): Connection;
 | 
				
			||||||
    getAccountInfo(publicKey: PublicKey): Promise<AccountInfo>;
 | 
					    getAccountInfo(publicKey: PublicKey): Promise<AccountInfo>;
 | 
				
			||||||
@@ -103,6 +120,8 @@ declare module '@solana/web3.js' {
 | 
				
			|||||||
    ): Promise<SignatureSuccess | TransactionError | null>;
 | 
					    ): Promise<SignatureSuccess | TransactionError | null>;
 | 
				
			||||||
    getTransactionCount(): Promise<number>;
 | 
					    getTransactionCount(): Promise<number>;
 | 
				
			||||||
    getTotalSupply(): Promise<number>;
 | 
					    getTotalSupply(): Promise<number>;
 | 
				
			||||||
 | 
					    getInflation(): Promise<Inflation>;
 | 
				
			||||||
 | 
					    getEpochSchedule(): Promise<EpochSchedule>;
 | 
				
			||||||
    getRecentBlockhash(): Promise<[Blockhash, FeeCalculator]>;
 | 
					    getRecentBlockhash(): Promise<[Blockhash, FeeCalculator]>;
 | 
				
			||||||
    requestAirdrop(
 | 
					    requestAirdrop(
 | 
				
			||||||
      to: PublicKey,
 | 
					      to: PublicKey,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,16 +68,15 @@ type VoteAccountStatus = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Network Inflation parameters
 | 
					 * Network Inflation parameters
 | 
				
			||||||
 | 
					 * (see https://docs.solana.com/book/v/master/implemented-proposals/ed_overview)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @typedef {Object} Inflation TODO - link to book terminology?
 | 
					 * @typedef {Object} Inflation
 | 
				
			||||||
 * @property {number} foundation TODO - link to book terminology?
 | 
					 * @property {number} foundation 
 | 
				
			||||||
 * @property {number} foundation_term TODO - link to book terminology?
 | 
					 * @property {number} foundation_term
 | 
				
			||||||
 * @property {number} grant TODO - link to book terminology?
 | 
					 * @property {number} initial
 | 
				
			||||||
 * @property {number} grant_term TODO - link to book terminology?
 | 
					 * @property {number} storage
 | 
				
			||||||
 * @property {number} initial TODO - link to book terminology?
 | 
					 * @property {number} taper
 | 
				
			||||||
 * @property {number} storage TODO - link to book terminology?
 | 
					 * @property {number} terminal
 | 
				
			||||||
 * @property {number} taper TODO - link to book terminology?
 | 
					 | 
				
			||||||
 * @property {number} terminal TODO - link to book terminology?
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
const GetInflationResult = struct({
 | 
					const GetInflationResult = struct({
 | 
				
			||||||
  foundation: 'number',
 | 
					  foundation: 'number',
 | 
				
			||||||
@@ -88,6 +87,25 @@ const GetInflationResult = struct({
 | 
				
			|||||||
  terminal: 'number',
 | 
					  terminal: 'number',
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EpochSchedule parameters
 | 
				
			||||||
 | 
					 * (see https://docs.solana.com/book/v/master/terminology#epoch)
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @typedef {Object} EpochSchedule
 | 
				
			||||||
 | 
					 * @property {number} slots_per_epoch
 | 
				
			||||||
 | 
					 * @property {number} leader_schedule_slot_offset
 | 
				
			||||||
 | 
					 * @property {boolean} warmup
 | 
				
			||||||
 | 
					 * @property {number} first_normal_epoch
 | 
				
			||||||
 | 
					 * @property {number} first_normal_slot
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const GetEpochScheduleResult = struct({
 | 
				
			||||||
 | 
					  slots_per_epoch: 'number',
 | 
				
			||||||
 | 
					  leader_schedule_slot_offset: 'number',
 | 
				
			||||||
 | 
					  warmup: 'boolean',
 | 
				
			||||||
 | 
					  first_normal_epoch: 'number',
 | 
				
			||||||
 | 
					  first_normal_slot: 'number',
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createRpcRequest(url): RpcRequest {
 | 
					function createRpcRequest(url): RpcRequest {
 | 
				
			||||||
  const server = jayson(async (request, callback) => {
 | 
					  const server = jayson(async (request, callback) => {
 | 
				
			||||||
    const options = {
 | 
					    const options = {
 | 
				
			||||||
@@ -130,6 +148,16 @@ const GetInflationRpcResult = struct({
 | 
				
			|||||||
  result: GetInflationResult,
 | 
					  result: GetInflationResult,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Expected JSON RPC response for the "getEpochSchedule" message
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const GetEpochScheduleRpcResult = struct({
 | 
				
			||||||
 | 
					  jsonrpc: struct.literal('2.0'),
 | 
				
			||||||
 | 
					  id: 'string',
 | 
				
			||||||
 | 
					  error: 'any?',
 | 
				
			||||||
 | 
					  result: GetEpochScheduleResult,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Expected JSON RPC response for the "getBalance" message
 | 
					 * Expected JSON RPC response for the "getBalance" message
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -678,7 +706,7 @@ export class Connection {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Fetch the cluster Inflation parameters (TODO - book link/terminology?)
 | 
					   * Fetch the cluster Inflation parameters
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  async getInflation(): Promise<GetInflationRpcResult> {
 | 
					  async getInflation(): Promise<GetInflationRpcResult> {
 | 
				
			||||||
    const unsafeRes = await this._rpcRequest('getInflation', []);
 | 
					    const unsafeRes = await this._rpcRequest('getInflation', []);
 | 
				
			||||||
@@ -690,6 +718,19 @@ export class Connection {
 | 
				
			|||||||
    return GetInflationResult(res.result);
 | 
					    return GetInflationResult(res.result);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Fetch the Epoch Schedule parameters
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  async getEpochSchedule(): Promise<GetEpochScheduleRpcResult> {
 | 
				
			||||||
 | 
					    const unsafeRes = await this._rpcRequest('getEpochSchedule', []);
 | 
				
			||||||
 | 
					    const res = GetEpochScheduleRpcResult(unsafeRes);
 | 
				
			||||||
 | 
					    if (res.error) {
 | 
				
			||||||
 | 
					      throw new Error(res.error.message);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    assert(typeof res.result !== 'undefined');
 | 
				
			||||||
 | 
					    return GetEpochScheduleResult(res.result);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Fetch the minimum balance needed to exempt an account of `dataLength`
 | 
					   * Fetch the minimum balance needed to exempt an account of `dataLength`
 | 
				
			||||||
   * size from rent
 | 
					   * size from rent
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -170,6 +170,43 @@ test('get inflation', async () => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('get epoch schedule', async () => {
 | 
				
			||||||
 | 
					  const connection = new Connection(url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mockRpc.push([
 | 
				
			||||||
 | 
					    url,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      method: 'getEpochSchedule',
 | 
				
			||||||
 | 
					      params: [],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      error: null,
 | 
				
			||||||
 | 
					      result: {
 | 
				
			||||||
 | 
					        first_normal_epoch: 8,
 | 
				
			||||||
 | 
					        first_normal_slot: 8160,
 | 
				
			||||||
 | 
					        leader_schedule_slot_offset: 8192,
 | 
				
			||||||
 | 
					        slots_per_epoch: 8192,
 | 
				
			||||||
 | 
					        warmup: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const epochSchedule = await connection.getEpochSchedule();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (const key of [
 | 
				
			||||||
 | 
					    'first_normal_epoch',
 | 
				
			||||||
 | 
					    'first_normal_slot',
 | 
				
			||||||
 | 
					    'leader_schedule_slot_offset',
 | 
				
			||||||
 | 
					    'slots_per_epoch',
 | 
				
			||||||
 | 
					  ]) {
 | 
				
			||||||
 | 
					    expect(epochSchedule).toHaveProperty(key);
 | 
				
			||||||
 | 
					    expect(epochSchedule[key]).toBeGreaterThan(0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  expect(epochSchedule).toHaveProperty('warmup');
 | 
				
			||||||
 | 
					  expect(epochSchedule.warmup).toBeTruthy();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('get slot', async () => {
 | 
					test('get slot', async () => {
 | 
				
			||||||
  const connection = new Connection(url);
 | 
					  const connection = new Connection(url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user