> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitflare.com/llms.txt
> Use this file to discover all available pages before exploring further.

# getLeaderSchedule

> Возвращает расписание лидеров для epoch

## Параметры

<ResponseField name="slot" type="number" optional>
  Получить расписание лидеров для epoch, содержащего данный слот
</ResponseField>

<ResponseField name="config" type="object" optional>
  <Expandable title="поля config">
    <ResponseField name="commitment" type="string" optional>
      Уровень commitment (processed, confirmed, finalized)
    </ResponseField>

    <ResponseField name="identity" type="string" optional>
      Возвращать результаты только для данного идентификатора валидатора (закодирован в base-58)
    </ResponseField>
  </Expandable>
</ResponseField>

## Ответ

<ResponseField name="result" type="object">
  <Expandable title="поля result">
    <ResponseField name="context" type="object">
      <ResponseField name="slot" type="number">
        Слот, при котором был обработан запрос
      </ResponseField>
    </ResponseField>

    <ResponseField name="value" type="object">
      Словарь идентификаторов валидаторов и их назначенных слотов лидеров
    </ResponseField>
  </Expandable>
</ResponseField>

## Примеры кода

### Базовый запрос

```bash theme={null}
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getLeaderSchedule"
}'
```

### Запрос для конкретного валидатора

```bash theme={null}
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getLeaderSchedule",
  "params": [{
    "identity": "VALIDATOR_IDENTITY"
  }]
}'
```

### Использование web3.js

```typescript theme={null}
import { Connection } from '@solana/web3.js';

const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');

// Get leader schedule
const leaderSchedule = await connection.getLeaderSchedule();
console.log('Leader schedule:', leaderSchedule.value);

// Get validator's leader slots
async function getValidatorLeaderSlots(validatorIdentity: string) {
  const schedule = await connection.getLeaderSchedule({
    identity: validatorIdentity
  });
  
  if (!schedule.value) {
    return {
      hasSlots: false,
      slots: []
    };
  }
  
  const slots = schedule.value[validatorIdentity] || [];
  
  return {
    hasSlots: slots.length > 0,
    slots,
    totalSlots: slots.length,
    context: schedule.context
  };
}
```

## Примечания

1. Возвращает расписание лидеров для текущего или указанного epoch
2. Можно фильтровать, чтобы показывать только слоты конкретного валидатора
3. Слоты лидеров назначаются валидаторам на основе веса стейка
4. Расписание фиксировано на протяжении всего epoch
5. Ответ включает слот, при котором был обработан запрос

## Лучшие практики

1. Используйте подходящий уровень commitment в зависимости от ваших потребностей
2. Фильтруйте по идентификатору валидатора, когда интересуют только конкретные валидаторы
3. Кэшируйте результаты при необходимости для снижения нагрузки на RPC
4. Следите за изменениями в расписании лидеров
5. Используйте совместно с другими методами, связанными с валидаторами

## Распространённые ошибки

| Код    | Сообщение                        | Решение                                                   |
| ------ | -------------------------------- | --------------------------------------------------------- |
| -32601 | Method not found                 | Убедитесь, что вы подключены к узлу Solana RPC            |
| -32602 | Invalid params                   | Проверьте параметры slot и identity                       |
| -32007 | Schedule information unavailable | Узел может выполнять начальную загрузку или синхронизацию |

## Примеры использования

1. **Анализ валидатора**
   ```typescript theme={null}
   interface ValidatorMetrics {
     identity: string;
     totalSlots: number;
     slotDistribution: number[];
     averageGap: number;
     maxGap: number;
     minGap: number;
   }

   async function analyzeValidatorSlots(
     validatorIdentity: string
   ): Promise<ValidatorMetrics> {
     const schedule = await connection.getLeaderSchedule({
       identity: validatorIdentity
     });
     
     if (!schedule.value || !schedule.value[validatorIdentity]) {
       throw new Error('No leader slots found for validator');
     }
     
     const slots = schedule.value[validatorIdentity].sort((a, b) => a - b);
     const gaps = [];
     
     for (let i = 1; i < slots.length; i++) {
       gaps.push(slots[i] - slots[i - 1]);
     }
     
     return {
       identity: validatorIdentity,
       totalSlots: slots.length,
       slotDistribution: slots,
       averageGap: gaps.reduce((sum, gap) => sum + gap, 0) / gaps.length,
       maxGap: Math.max(...gaps),
       minGap: Math.min(...gaps)
     };
   }
   ```

2. **Мониторинг расписания лидеров**
   ```typescript theme={null}
   interface ScheduleAlert {
     type: 'change' | 'gap' | 'distribution';
     message: string;
     validator: string;
     details: any;
   }

   class ScheduleMonitor {
     private previousSchedule: Map<string, number[]> = new Map();
     
     async monitorSchedule(
       maxGap: number = 100,
       minSlots: number = 10
     ): Promise<ScheduleAlert[]> {
       const schedule = await connection.getLeaderSchedule();
       const alerts: ScheduleAlert[] = [];
       
       for (const [validator, slots] of Object.entries(schedule.value)) {
         const previousSlots = this.previousSchedule.get(validator) || [];
         
         // Check for significant changes
         if (previousSlots.length > 0) {
           const change = Math.abs(slots.length - previousSlots.length);
           if (change > minSlots) {
             alerts.push({
               type: 'change',
               message: `Validator ${validator} slot count changed by ${change}`,
               validator,
               details: { previous: previousSlots.length, current: slots.length }
             });
           }
         }
         
         // Check for large gaps
         const sortedSlots = [...slots].sort((a, b) => a - b);
         for (let i = 1; i < sortedSlots.length; i++) {
           const gap = sortedSlots[i] - sortedSlots[i - 1];
           if (gap > maxGap) {
             alerts.push({
               type: 'gap',
               message: `Large gap of ${gap} slots found for validator ${validator}`,
               validator,
               details: { gap, slot1: sortedSlots[i - 1], slot2: sortedSlots[i] }
             });
           }
         }
         
         this.previousSchedule.set(validator, slots);
       }
       
       return alerts;
     }
   }
   ```

3. **Планирование epoch**
   ```typescript theme={null}
   interface EpochPlan {
     currentEpoch: number;
     nextEpoch: number;
     slotsPerEpoch: number;
     validatorSlots: Map<string, number>;
     slotDistribution: Map<number, string[]>;
   }

   async function planEpoch(): Promise<EpochPlan> {
     const schedule = await connection.getLeaderSchedule();
     const epochInfo = await connection.getEpochInfo();
     
     const validatorSlots = new Map<string, number>();
     const slotDistribution = new Map<number, string[]>();
     
     for (const [validator, slots] of Object.entries(schedule.value)) {
       validatorSlots.set(validator, slots.length);
       
       for (const slot of slots) {
         if (!slotDistribution.has(slot)) {
           slotDistribution.set(slot, []);
         }
         slotDistribution.get(slot)!.push(validator);
       }
     }
     
     return {
       currentEpoch: epochInfo.epoch,
       nextEpoch: epochInfo.epoch + 1,
       slotsPerEpoch: epochInfo.slotsInEpoch,
       validatorSlots,
       slotDistribution
     };
   }
   ```
