Модель безопасности
В сети POA работает один производитель блоков и один или несколько независимых верификаторов. Эта модель доверия проще, чем система с набором валидаторов, однако границы, через которые поступают недоверенные данные, всё равно требуют защиты. На этой странице описаны рассмотренные векторы атак и механизмы противодействия каждому из них.
Границы доверия
Заголовок раздела «Границы доверия»Существуют четыре границы, через которые недоверенные данные попадают в систему:
- Пользователь → RPC: кошельки отправляют подписанные транзакции через
eth_sendRawTransactionили/wallet/broadcasttransaction. На входе — недоверенные hex-данные. Для Ethereum raw-транзакций размер ограничивается ещё до декодирования, а protobuf-данные Tron декодируются и проходят структурную валидацию перед добавлением в очередь. Пока производство блоков остановлено, новые транзакции отклоняются с повторяемой ошибкой (-32003с сообщениемproducer_halted:; в Tron код 9) и в очередь не попадают. - RPC → исполнитель: проверенные транзакции находятся в пуле
pending_transactions, пока производитель блоков не заберет их. Исполнитель повторно определяет адрес отправителя по подписи. - Производитель → верификатор: верификатор получает блоки через Erlang distribution. Он не доверяет никаким данным: повторно исполняет каждую транзакцию и пересчитывает каждый хеш.
- Пользователь → прекомпайл: данные вызова (calldata) к прекомпайлам (HTLC, bridge refill/mint) разбираются и проверяются внутри каждого контракта.
Валидация на уровне RPC
Заголовок раздела «Валидация на уровне RPC»Каждая транзакция проходит несколько проверок до попадания в пул ожидания:
| Проверка | Что предотвращает |
|---|---|
| Декодирование hex | Некорректный ввод, наличие не шестнадцатеричных символов |
| Лимит Ethereum raw (4 КБ) | DoS-атаки через слишком большие запросы в eth_sendRawTransaction. Проверяется до декодирования. |
| Декодирование RLP / protobuf | Структурно некорректные транзакции |
| Chain ID | Повторное исполнение в другой сети (транзакция подписана для Ethereum mainnet, но отправлена в 2D) |
| Восстановление подписи | Невалидные подписи, пластичные (malleable) подписи (EIP-2 s-value) |
| Валидация nonce | Устаревшие транзакции (nonce < текущего nonce аккаунта) отклоняются. Будущие nonce (future nonce) ограничены значением +100. |
Некорректные адреса и топики (topics) в eth_getLogs возвращают ошибку, а не приводят к сбою обработчика.
Защита от повторного исполнения и управление nonce
Заголовок раздела «Защита от повторного исполнения и управление nonce»Каждый аккаунт имеет последовательный nonce. Исполнитель проверяет, что nonce транзакции точно совпадает с текущим nonce аккаунта. Транзакция не может быть выполнена дважды, так как nonce увеличивается после каждого выполнения.
Повторное исполнение в другой сети блокируется как на уровне RPC, так и в исполнителе: транзакции должны содержать корректный идентификатор сети (77 для POA). Транзакции формата pre-EIP-155 (без chain ID) отклоняются.
Дублирование хешей транзакций обрабатывается с помощью ON CONFLICT DO NOTHING при вставке в базу данных. Повторная отправка той же подписанной транзакции не дает никакого эффекта.
Отдельный аккаунт для POA
Заголовок раздела «Отдельный аккаунт для POA»Создайте новый ключ и сид-фразу для основной сети POA. Не импортируйте приватный ключ, сид-фразу или файл ключей, ранее использовавшийся в другой сети или развёртывании. В частности, архивную транзакцию, подписанную этим ключом для chain ID 77, может отправить в основной сети POA кто угодно, когда совпадёт nonce и на аккаунте будет достаточно средств: новая подпись и ваше участие не нужны. Проверка chain ID не различает развёртывания с одинаковым ID; проверка nonce не делает повторное использование ключа безопасным. Храните старые ключи отдельно и не пополняйте их адреса в POA. Explorer и RPC никогда не требуют сид-фразу.
Антиспам-троттлинг
Заголовок раздела «Антиспам-троттлинг»Все транзакции бесплатны (комиссия = 0). Спам предотвращается за счет экспоненциальной задержки на уровне производителя блоков. Подробности описаны в разделе Бесплатные транзакции.
Троттлинг — это индивидуальная задержка (cooldown) для каждого отправителя, а не жесткая блокировка. Когда количество транзакций отправителя в скользящем окне превышает порог, из обработки временно исключаются только ожидающие (pending) транзакции этого конкретного отправителя на время действия задержки. Как только индивидуальная задержка истекает, его следующая транзакция снова становится доступной для включения в блок. Остальные отправители при этом не затрагиваются (защита от head-of-line blocking), а очередь ограниченного отправителя постепенно разгружается, а не блокируется до сдвига скользящего окна.
Tron-транзакции содержат установленный кошельком параметр expiration (обычно 30-60 секунд). Если ожидающая Tron-транзакция задерживается дольше своего срока действия, производитель удаляет её из пула до исполнения блока, вместо того чтобы записывать в блок статус status=error. Сообщение “throttled дольше validity window” не несет полезной информации, кроме внутренней механики планирования сети.
Устаревшие транзакции в пуле (старше 10 минут) очищаются автоматически.
Верификация подписей
Заголовок раздела «Верификация подписей»Адрес отправителя проверяется криптографически и никогда не берется из пользовательского ввода:
- Ethereum-транзакции: отправитель восстанавливается из ECDSA-подписи с помощью
secp256k1recovery. Восстановленный адрес используется для всех операций с балансом и nonce. - Tron-транзакции: подпись хранится вместе с сырыми protobuf-данными. При исполнении адрес отправителя заново вычисляется из
sha256(raw_data) + signatureи сравнивается с сохранённым. Любые расхождения приводят к отклонению транзакции.
Компоненты подписи (r, s), длина которых превышает 32 байта, отклоняются до выполнения padding. Подписи с высоким s-значением (high-s, уязвимость EIP-2 malleability) отклоняются как на уровне RPC, так и в исполнителе.
Независимость верификатора
Заголовок раздела «Независимость верификатора»Верификатор не доверяет никаким данным от производителя блоков. Для каждого блока он независимо:
- Вычисляет хеши транзакций из сырых байтов (не доверяя хешам, заявленным производителем).
- Пересчитывает корень состояния (state root) по своей локальной базе данных.
- Проверяет корень транзакций (transactions root), state root и хеш блока.
- Для генезис-блока: фиксирует канонические timestamp и transactions root на основе известных констант.
Расхождение в любом из этих значений приводит к остановке верификатора. Подробности описаны в разделе Запуск верификатора.
Ограничения на уровне базы данных
Заголовок раздела «Ограничения на уровне базы данных»История, работающая в режиме «только добавление» (append-only), защищена правилами PostgreSQL, которые блокируют операции UPDATE и DELETE для таблиц blocks и transactions. Схема состояния использует уровень изоляции SERIALIZABLE для всех блоков, что предотвращает состояние гонки (race conditions) между конкурентными транзакциями.
Текущие границы
Заголовок раздела «Текущие границы»- Приватность: балансы и суммы переводов видны любому, кто запустит верификатор. Приватный слой находится в разработке.
- Подпись блоков: производитель подписывает хеши блоков через
2d-hsm; верификатор независимо проверяет подпись и содержимое блока. См. Подпись в TEE.