НОВОЕ: Helius приобретает Light Protocol
Перегрузка Solana: как лучше отправлять транзакции Solana
Блог/Основы

Перегрузка Solana: как лучше отправлять транзакции Solana

Инженер по интеграциямHet Dagli в XHet Dagli в LinkedIn
Чтение: 5 мин

Введение

«Сбой симуляции транзакции: хеш блока не найден». «Не удалось отправить транзакцию». Эти сообщения об ошибках стали слишком привычными. Из-за перегрузки сети даже базовые транзакции превратились в игру случая. Но этих проблем можно избежать.

В этом руководстве мы рассмотрим простые стратегии для эффективной работы в периоды высокой нагрузки и успешного включения транзакций в блоки. Мы подробно разберём способы борьбы с перегрузкой сети, включая приоритетные комиссии, оптимизацию вычислительных единиц и эксклюзивный секретный приём Helius, который поможет всегда включать ваши транзакции в блоки.

В этом руководстве мы рассмотрим:

  • Использование сериализованных транзакций для расчёта приоритетных комиссий
  • Использование ключей аккаунтов для расчёта приоритетных комиссий
  • Продвинутые стратегии работы с приоритетными комиссиями
  • Методы оптимизации транзакций
  • Использование стейкинговых эндпоинтов для гарантированной доставки

Приоритетные комиссии

Приоритетные комиссии работают как механизм ставок и позволяют сообщить валидаторам о важности вашей транзакции. Размер этих комиссий, выраженный в микролампортах за вычислительную единицу, зависит от конкретных аккаунтов, с которыми взаимодействует транзакция. Это создаёт независимый рынок комиссий для каждого аккаунта. Если назначать комиссии с учётом перегрузки конкретных аккаунтов, можно значительно повысить вероятность включения транзакции в следующий блок.

Далее мы рассмотрим несколько способов правильно настроить приоритетные комиссии с помощью Priority Fee API от Helius:

Сериализованная транзакция

Самый простой способ настроить приоритетные комиссии — использовать сериализованную транзакцию. Сериализованная транзакция — это двоичное представление транзакции, преобразованное в буфер сетевого формата для передачи по сети.

  1. Сериализуйте транзакцию и передайте её в API:
Код
const serializedTx = transaction.serialize();

const response = await fetch(heliusEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'helius-example',
    method: 'getPriorityFeeEstimate',
    params: [{
      transaction: serializedTx,
      options: { recommended: true }
    }]
  }),
});

const { result } = await response.json();
const priorityFee = result.priorityFeeEstimate;
  1. Добавьте рекомендованную комиссию в транзакцию — порядок инструкций не имеет значения:
Код
transaction.add(
  ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFee
  })
);

Ключи аккаунтов

Другой способ — передать в Priority Fee API список ключей аккаунтов, задействованных в транзакции:‍

  1. Извлеките ключи аккаунтов из транзакции:
Код
const transaction = new Transaction();

// Add your instructions to the transaction

// Extract all account keys from the transaction
const accountKeys = transaction.compileMessage().accountKeys;

// Convert PublicKeys to base58 strings
const publicKeys = accountKeys.map(key => key.toBase58());
  1. Передайте ключи аккаунтов в Priority Fee API:
Код
const response = await fetch(heliusEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'helius-example',
    method: 'getPriorityFeeEstimate',
    params: [{
      accountKeys: publicKeys,
      options: { recommended: true }
    }]
  }),
});

const { result } = await response.json();
const priorityFee = result.priorityFeeEstimate;
  1. Добавьте рекомендованную комиссию в транзакцию:
Код
transaction.add(
  ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFee
  })
);

Оба способа работают, но мы рекомендуем использовать сериализованные транзакции. При использовании ключей аккаунтов необходимо вручную отслеживать и указывать все связанные аккаунты. Если пропустить хотя бы один из них, оценка комиссии может оказаться неточной. 

Метод сериализованной транзакции исключает этот риск: он автоматически учитывает все необходимые аккаунты и точнее оценивает комиссию на основе полного контекста транзакции.

Продвинутые стратегии работы с приоритетными комиссиями

В большинстве случаев достаточно использовать сериализованную транзакцию с рекомендованной приоритетной комиссией. Но для более точного контроля Priority Fee API позволяет запрашивать оценки для разных уровней приоритета и учитывать пустые слоты.

Уровни приоритета

Вот пример запроса всех уровней приоритетной комиссии:

Код
const response = await fetch(heliusEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'helius-example',
    method: 'getPriorityFeeEstimate',
    params: [{
      transaction: serializedTx,
      options: {
        includeAllPriorityFeeLevels: true
      }
    }]
  }),
});

const { result } = await response.json();
console.log(result.priorityFeeLevels);

Запрос вернёт объект с разными уровнями приоритета:

Код
{
  "priorityFeeLevels": {
    "min": 10000.0,
    "low": 10000.0,
    "medium": 10000.0,
    "high": 100000.0,
    "veryHigh": 5483924.800000011,
    "unsafeMax": 8698904817.0
  }
}

Уровни приоритета соответствуют разным процентилям недавних комиссий за транзакции:

  • min: 0-й процентиль
  • low: 25-й процентиль
  • medium: 50-й процентиль
  • high: 75-й процентиль
  • veryHigh: 95-й процентиль
  • unsafeMax: 100-й процентиль (используйте с осторожностью)

Чтобы ещё больше повысить вероятность включения транзакций в блоки, используйте уровни приоритета high или very high. Однако соблюдайте осторожность с более высокими уровнями приоритета, особенно veryHigh и unsafeMax: они могут значительно увеличить стоимость транзакций.‍

Оценка пустых слотов

Недавнее обновление Priority Fee API сделало оценку комиссий точнее благодаря учёту пустых слотов. Если в блоках нет транзакций для определённого аккаунта, API можно настроить так, чтобы считать комиссию в этих слотах нулевой. Это повышает точность оценки в периоды низкой сетевой активности:

Код
const response = await fetch(heliusEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'helius-example',
    method: 'getPriorityFeeEstimate',
    params: [{
      transaction: serializedTx,
      options: {
        recommended: true,
        evaluateEmptySlotAsZero: true
      }
    }]
  }),
});

Если параметр evaluateEmptySlotAsZero включён, API:

  • Определяет блоки без транзакций для ваших аккаунтов
  • Считает комиссию в этих пустых слотах нулевой
  • Снижает оценку в периоды низкой перегрузки
  • Предотвращает переплату при низкой сетевой активности

Стратегии оптимизации транзакций

Помимо приоритетных комиссий, оптимизация транзакций включает несколько ключевых компонентов, которые вместе повышают вероятность их включения в блоки:

Управление вычислительными единицами

  1. Используйте Helius SDK, чтобы получить оптимальное количество вычислительных единиц для транзакции:‍
Код
const response = await helius.rpc.getComputeUnits({
  transaction: serializedTransaction
});

const computeUnits = response.computeUnits;
  1. Добавьте лимит вычислительных единиц в транзакцию:
Код
transaction.add(
  ComputeBudgetProgram.setComputeUnitLimit({
    units: computeUnits
  })
);

Уровни подтверждения

‍Для большинства приложений уровень подтверждения processed обеспечивает оптимальный баланс. Он:

  • Обеспечивает самое быстрое подтверждение
  • Даёт достаточный уровень безопасности для большинства сценариев
  • Снижает риск истечения срока действия хеша блока
  • Сводит к минимуму количество отклонённых транзакций при перегрузке

Всегда используйте один уровень подтверждения для отправки и подтверждения транзакций, чтобы поведение приложения оставалось согласованным.

Конфигурация RPC

Установите maxRetries равным 0 и реализуйте собственную логику повторных попыток, чтобы лучше контролировать повторную отправку транзакций. Используйте skipPreflight: true, чтобы сократить задержку. Это особенно полезно в периоды сильной перегрузки:

Код
const signature = await connection.sendTransaction(transaction, {
  maxRetries: 0,
  skipPreflight: true
});

Использование стейкингового эндпоинта

Стейкинговый эндпоинт Helius предоставляет прямой гарантированный доступ к стейкинговым соединениям, поэтому вам не нужно вручную оптимизировать приоритетные комиссии:

Код
const connection = new Connection(
  'https://staked.helius-rpc.com?api-key=YOUR_API_KEY'
);

// Transaction will be processed with optimal priority
const signature = await connection.sendTransaction(transaction);

Стейкинговый эндпоинт:

  • Гарантирует доступ к пропускной способности стейкинговых соединений
  • Снижает количество сбоев транзакций при перегрузке
  • Ускоряет распространение транзакций благодаря выделенной инфраструктуре

Заключение

Правильное использование приоритетных комиссий крайне важно для успешного включения транзакций в блоки Solana, особенно при перегрузке сети. Priority Fee API от Helius и рассмотренные стратегии помогут значительно повысить долю успешных транзакций, сохраняя баланс между надёжностью и стоимостью. Следите за ситуацией и адаптируйтесь к состоянию сети, чтобы получать оптимальные результаты.

Спасибо, что дочитали до конца! Надеемся, это руководство помогло вам понять, как оптимизировать транзакции в Solana. Подпишитесь на нашу рассылку, чтобы всегда быть в курсе новостей Solana. 

Готовы узнать больше?

Читайте новые статьи в блоге Helius и продолжайте знакомство с Solana уже сегодня.

Подпишитесь на Helius

Следите за новостями разработки на Solana и получайте уведомления о наших публикациях

Увеличенное изображение