Архитектура мемпула
Мемпул управляет ожидающими транзакциями — от приёма через оценку до извлечения при производстве блока.
Конвейер
Network (gossipsub /savitri/tx/1)
│
▼
Prevalidation (stateless)
│ signature format, size limits
▼
Admission Control
│ quota check, per-sender cap
▼
Stateful Validation
│ nonce, balance, fee limits
▼
SIMD Batch Scoring
│ fee * 0.7 + class * 0.3
▼
Score Cache (LRU)
│
▼
Pending Pool
│
▼
drain_for_block_production()
│ top-N by score, final_validation
▼
Block Proposer
Классы транзакций
| Класс | Приоритет | Применение |
|---|---|---|
FederatedUpdate | 1.0 (наивысший) | Обновления FL-модели |
Financial | 0.8 | Переводы токенов |
Governance | 0.7 | Голоса, предложения |
IoTData | 0.5 | Данные датчиков |
Квоты приёма
| Класс | Макс. ожидающих | Лимит на отправителя |
|---|---|---|
| Financial | 50 000 | 512 |
| IoT | 100 000 | 512 |
| Global | 100 000 | 512 |
Функция drain_fair_batch() вызывает record_removal() для корректного уменьшения счётчиков классов при извлечении транзакций (исправлено в Round 6).
SIMD-оценка
Формула оценки
score = fee_normalized * fee_weight + class_priority * class_weight
По умолчанию: fee_weight = 0.7, class_weight = 0.3.
Реализация для конкретных архитектур
| Архитектура | Инструкции | Каналы | Мин. размер пакета |
|---|---|---|---|
| x86_64 (AVX2+FMA) | _mm256_set1_pd, _mm256_fmadd_pd | 4 double | 32 |
| ARM (NEON) | vdupq_n_f64, vfmaq_f64 | 2 double | 32 |
| Резервный | Скалярный цикл | 1 | Всегда |
Для пакетов менее 32 транзакций используется скалярное вычисление, так как накладные расходы на инициализацию SIMD превышают выгоду.
Адаптивные веса (опционально)
При включённом флаге функции adaptive_weights веса корректируются на основе:
- Распределение комиссий: при кластеризации комиссий в высоком диапазоне увеличивается fee_weight
- Разнообразие классов: при большом количестве разных классов увеличивается class_weight
- Историческая пропускная способность: корректировка на основе последних блоков
Параметры:
base_fee_weight = 0.7
base_class_weight = 0.3
adaptation_rate = 0.1 (сглаживание)
fee_threshold_high = 2,000,000,000
fee_threshold_low = 500,000,000
class_diversity_threshold = 0.5
Кеш оценок
LRU-кеш позволяет избежать повторного вычисления оценок:
| Параметр | Разработка | Продакшн |
|---|---|---|
| Размер кеша | 100 записей | 10 000 записей |
| TTL | 60 секунд | 300 секунд |
Управление nonce
Стандартный процесс
- Транзакция поступает с nonce N
- Проверка:
N >= account.storage_nonce - Отслеживание в
pending_noncesHashMap при извлечении - Фиксация nonce после финализации блока
Допуск пробелов
Пробел в nonce до 5000 принимается для восстановления после длительных задержек (увеличено с 1000 в Round 11).
Исправление холодного старта
При storage_nonce=0 AND pending_nonces=0 в качестве начальной точки принимается наименьший доступный nonce. Это обрабатывает случай, когда транзакции были извлечены, но блок так и не был зафиксирован предыдущим предложителем.
Сброс nonce
Генератор транзакций сбрасывает локальный nonce при local_nonce > storage_nonce + 200 (MAX_NONCE_AHEAD). Ранее локальные nonce могли уйти в дрейф до 2000+, тогда как storage находился на 84, что приводило к отклонению всех транзакций.
Защита от повторного использования
Хеши транзакций отслеживаются для предотвращения атак повторного воспроизведения. После обнаружения хеша транзакции повторные отправки отклоняются.
Валидация комиссий
FeeLimits {
min_fee: 100_000_000_000_000, // 0.0001 SAVT
max_fee: 1_000_000_000_000_000_000, // 1.0 SAVT
}
Флаги функций
| Флаг | Описание |
|---|---|
simd | SIMD-оптимизированная оценка (по умолчанию) |
cache | Кеш оценок (по умолчанию) |
adaptive_weights | Динамическая корректировка весов |