Перейти к основному содержанию

Documentation Index

Fetch the complete documentation index at: https://docs.raydium.io/llms.txt

Use this file to discover all available pages before exploring further.

Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Каждая транзакция Solana устанавливает (явно или неявно) два параметра: лимит вычислительных единиц (максимум CU, которые может потребить tx; по умолчанию 200 000 × количество инструкций с ограничением по транзакции) и комиссию за приоритет в микро-ламортах за CU. Недостаточный размер любого параметра приводит к отказу транзакции — слишком низкий лимит CU вызывает ProgramFailedToComplete; слишком низкая комиссия за приоритет оставляет транзакцию неподтверждённой до истечения срока.

Два параметра

import { ComputeBudgetProgram } from "@solana/web3.js";

const tx = new Transaction()
  .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 250_000 }))
  .add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 50_000 }))
  .add(yourRaydiumSwapIx);
  • setComputeUnitLimit(units) — ограничивает вычисления; транзакция оплачивает не более units CU.
  • setComputeUnitPrice(microLamports) — ставка комиссии за приоритет в микро-ламортах за CU. Общая комиссия за приоритет = units × microLamports × 1e-6 ламортов.
Расчёт стоимости: лимит 250k CU при 50k микро-ламортов/CU стоит 250_000 × 50_000 / 1e6 = 12,500 ламортов ≈ 0,0000125 SOL ≈ $0,003 при SOL = $200. Комиссии за приоритет такого размера — едва заметны для большинства пользовательских свопов, но материальны для ботов, выполняющих 1000 tx/день.

Бенчмарки CU по инструкциям

Бенчмарки из журналов выполнения на mainnet, усреднённые по последним запускам. Цифры приблизительные (±15%); переизмеряйте для ваших конкретных потоков.
ИнструкцияSPL TokenToken-2022 (простой)Token-2022 (трансфер с комиссией)
CPMM initialize_pool180 000200 000
CPMM swap_base_input140 000180 000200 000
CPMM swap_base_output150 000185 000205 000
CPMM deposit130 000160 000180 000
CPMM withdraw120 000150 000170 000
CLMM create_pool70 00085 000
CLMM open_position_v2120 000140 000160 000
CLMM increase_liquidity_v2150 000175 000195 000
CLMM decrease_liquidity_v2140 000165 000185 000
CLMM swap_v2 (0 пересечений тиков)170 000205 000225 000
CLMM swap_v2 (1 пересечение тика)220 000255 000275 000
CLMM swap_v2 (3 пересечения тиков)320 000355 000375 000
CLMM collect_fee80 00095 000105 000
AMM v4 swap_base_in140 000
AMM v4 deposit120 000
AMM v4 withdraw110 000
Farm v6 create_farm70 00085 000
Farm v6 deposit (1 слот награды)130 000155 000175 000
Farm v6 deposit (3 слота награды)220 000255 000275 000
Farm v6 withdrawсовпадает с deposit
Farm v6 harvestсовпадает с deposit
Farm v3/v5 deposit100 000
LaunchLab initialize100 000
LaunchLab buy_exact_in140 000
LaunchLab graduate250 000
Строка «пересечения тиков» для CLMM — это самая большая переменная CU. Если вы не знаете, сколько тиков пересечёт свап, планируйте наихудший случай — 8 пересечений — это жёсткий лимит (программа загружает максимум 8 массивов тиков).

Составные транзакции

Суммируйте отдельные бюджеты и добавьте:
  • +1 500 CU за каждый фрейм CPI — фиксированные накладные расходы runtime для каждого перекрёстного вызова программы.
  • +20 000 CU за создание ATAcreate_associated_token_account не бесплатна.
  • +5 000 CU за setComputeUnitLimit / setComputeUnitPrice каждая.
Пример: пользовательский свап, создающий выходной ATA и обёртывающий нативный SOL:
wrap_sol (create_ata + system transfer + sync_native)   ≈ 30 000
CPMM swap_base_input (SPL)                              ≈ 140 000
close_account (unwrap)                                  ≈ 5 000
ComputeBudget инструкции                                ≈ 10 000
────────────────────────────────────────────────────────
Итого                                                   ≈ 185 000 → бюджет 250 000
Запас: установите лимит CU примерно на 25% выше ожидаемого использования. Недооценка стоит всю транзакцию; переоценка только пропорционально повышает стоимость комиссии за приоритет (комиссия за приоритет — это units × microLamports, поэтому переоценка на ~25% стоит на 25% больше в приоритетной комиссии).

Оценка комиссии за приоритет

Локальный рынок комиссий Solana означает, что комиссии за приоритет — для каждого записываемого аккаунта. Транзакция, которая записывает на горячий аккаунт (популярное состояние пула), платит больше, чем транзакция, записывающая на холодный аккаунт. Глобальный уровень комиссий — неправильная метрика для свопов Raydium; вам нужны комиссии на конкретных пулах, которые вы трогаете.

Стратегия 1: оценитель RPC-провайдера

Каждый крупный RPC-провайдер публикует оценитель комиссий за приоритет, который запрашивает недавние комиссии на конкретных аккаунтах:
// Helius
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${apiKey}`, {
  method: "POST",
  body: JSON.stringify({
    jsonrpc: "2.0",
    id:      "fee-estimate",
    method:  "getPriorityFeeEstimate",
    params: [{
      accountKeys: [poolStatePubkey.toBase58()],
      options:     { priorityLevel: "High" },
    }],
  }),
});
const { result } = await response.json();
const microLamports = result.priorityFeeEstimate;
Уровни приоритета у большинства провайдеров: Min / Low / Medium / High / VeryHigh / UnsafeMax. Отображайте их на перцентили:
УровеньПерцентильСлучай использования
Min25-йФоновый, неспешный трафик ботов
Low50-йОбычные пользовательские свопы
Medium60-йПо умолчанию для UI кошельков
High75-йЧувствительный по времени арбитраж
VeryHigh95-йЛиквидации, последние шансы выхода
Провайдеры: Helius (getPriorityFeeEstimate), Triton (getRecentPrioritizationFees со списком аккаунтов), QuickNode (аналогично).

Стратегия 2: прямой RPC-запрос

Используйте стандартный RPC getRecentPrioritizationFees:
const fees = await connection.getRecentPrioritizationFees({
  lockedWritableAccounts: [poolStatePubkey],
});

// fees: Array<{ slot, prioritizationFee }>
// Последние N слотов; по умолчанию ~150 слотов.

const median = percentile(fees.map(f => f.prioritizationFee), 0.5);
Это ванильный метод RPC Solana; работает с любым провайдером. Минус: выборка мала (150 слотов ≈ 60 секунд) и шумна. Для более гладких оценок используйте агрегацию провайдера.

Стратегия 3: историческая самонастройка

Для ботов с постоянным потоком отслеживайте собственные скорости приземления и истечения:
целевой показатель за пул: 80% rate приземления за <30s
если current_land_rate < 80%: priorityFee += 10%
если current_land_rate > 95%: priorityFee -= 5%
Это самокорректируется быстрее, чем публичные оценители, и захватывает структуру за пулом, которую публичные оценители не всегда видят.

Обработка отказов из-за исчерпания CU

Симптом: транзакция падает с exceeded maximum number of instructions allowed (200000) или ProgramFailedToComplete. Диагностика:
solana confirm <tx-sig> -v
# Ищите "consumed N of M compute units" и какая инструкция исчерпала.
Исправления:
  1. Увеличьте лимит CU. Если ваша транзакция использовала 195k из бюджета 200k, увеличьте до 300k.
  2. Разделите транзакцию. Если вы достигли лимита 1,4M за транзакцию, разбейте на две транзакции. Фарм harvest then stake — классический случай для разделения при множественных наградах.
  3. Обрезьте аккаунты. Каждый дополнительный записываемый аккаунт добавляет ~2 000 CU. Удаление неиспользуемых аккаунтов помогает в маргинальных случаях.
  4. Используйте таблицы поиска. Поиск LUT — ~50 CU за разрешённый адрес, сэкономив 5 000 CU полной ссылки на аккаунт за запись.

Обработка застрявших транзакций

Симптом: транзакция отправлена, никогда не подтверждается, в итоге истекает с BlockhashNotFound. Диагностика:
  • getSignatureStatuses([sig]) возвращает null → лидер её не видел.
  • Возвращает { confirmationStatus: null } → лидер видел, но не включил.
Исправления:
  1. Увеличьте комиссию за приоритет. Переотправьте с 2× текущей комиссией.
  2. Перестройте со свежим блокхешем. Время жизни блокхеша ~60 секунд; сверх этого транзакция невалидна независимо от комиссий.
  3. Многорассылка по RPC. Некоторые RPC имеют лучшую связность с лидерами. Отправляйте параллельно 3–5 провайдерам.
  4. Переключитесь на Jito bundles. См. integration-guides/routing-and-mev. Бандлы обходят публичные очереди пакетов.
Скелет логики повтора:
async function submitWithRetry(buildTx, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const tx = await buildTx({
      priorityFee: basePriorityFee * Math.pow(1.5, attempt),
      blockhash:   (await connection.getLatestBlockhash()).blockhash,
    });

    try {
      const sig = await connection.sendRawTransaction(tx.serialize(), {
        skipPreflight: attempt > 0,  // пропустить после первой попытки, чтобы сэкономить задержку
      });

      const result = await connection.confirmTransaction(sig, "confirmed");
      if (result.value.err) {
        // Логическая ошибка; не повторяйте.
        throw result.value.err;
      }
      return sig;

    } catch (e) {
      if (isExpiredError(e)) continue;  // повтор
      if (isRevertError(e)) throw e;    // не повторяйте; детерминированный отказ
      throw e;
    }
  }
  throw new Error("submit: exhausted retries");
}

При перегрузке

Когда сеть перегружена (панели мониторинга Jupiter / Jito bundles показывают задолженность, задержка RPC растёт, темпы истечения tx растут), отрегулируйте:
ПараметрНормальные условияУсловия перегрузки
Лимит CU+25% выше оценки+25% выше оценки (без изменений)
Перцентиль комиссии за приоритет50-й75-й–95-й
Количество повторов35–7
Откат повтора500ms1000ms
Использовать Jito bundlesНеобязательноНастоятельно рекомендуется
Обновление блокхеша при повтореДаДа, обязательно
Мониторинг сигналов перегрузки:
  • 75-й перцентиль комиссии за приоритет > 500k микро-ламортов: перегрузка.
  • 50-й перцентиль чаевых Jito > 0,001 SOL: перегрузка.
  • RPC ответ p99 > 2s: проблема RPC или перегрузка.

Бюджетирование комиссий для ботов

Торговый бот, работающий ~1000 tx/день, нуждается в бюджете комиссии за приоритет. Примерная оценка:
Среднее CU за транзакцию:          ~250 000
50-й перцентиль комиссии:          ~20 000 микро-ламортов/CU
Стоимость за транзакцию:           250_000 × 20_000 × 1e-6 = 5_000 ламортов = 5e-6 SOL
Дневная стоимость (1000 tx):       5e-3 SOL ≈ $1 при SOL = $200
Месячная стоимость:                ~$30
Это минимум. При перегрузке умножьте на 5–10×. Планируйте ~$150–300/месяц в комиссиях за приоритет для бота с установившимся потоком. Боты, которые должны приземлиться в конкретные слоты (ликвидации, арб), постоянно платят 95-й перцентиль и тратят ~10× больше. Чаевые Jito bundle доминируют в этом масштабе — часто $1000+/месяц — но альтернатива (быть обогнанным или истечь) хуже.

Ловушки

1. Забытый лимит CU

По умолчанию 200k CU × (инструкции в tx). Свап с одной инструкцией по умолчанию 200k; этого достаточно для CPMM на SPL Token, но не для CLMM с пересечениями тиков или чего-либо Token-2022. Всегда устанавливайте явно.

2. Комиссия за приоритет на неправильном аккаунте

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

3. Комиссии масштабируются с лимитом CU

total_priority_fee = units × microLamports. Повышение units с 200k до 1M при 50k микро-ламортов/CU умножает комиссию за приоритет на 5×. Не переполняйте CU просто на всякий случай; измеряйте.

4. Версия транзакции по умолчанию

Legacy транзакции имеют меньше лимитов аккаунтов; V0 транзакции с таблицами поиска адресов открывают большие маршруты. SDK использует V0 по умолчанию в txVersion: TxVersion.V0. Не понижайте до legacy, если не нужна совместимость с кошельком.

5. skipPreflight скрывает ошибки CU

skipPreflight: true отправляет транзацию без локальной симуляции. Вы экономите ~100ms, но теряете раннюю обратную связь об исчерпании CU. Используйте только при повторах, а не при первой попытке.

Ссылки

Источники: