SymbioticDVN.t.sol
Обзор
Файл SymbioticDVN.t.sol содержит набор unit-тестов для смарт-контракта SymbioticDVN, реализованного на языке Solidity и предназначенного для кроссчейн-верификации сообщений. Основная цель тестов — проверить корректность работы функций контракта, связанных с запросом верификации сообщений, проверкой подписей валидаторов, достижением кворума, управлением валидаторами, поддерживаемыми цепочками, а также обработкой исключительных ситуаций (например, истечением таймаута или аварийной верификацией).
Данные тесты написаны с использованием библиотеки forge-std (фреймворк Foundry), что обеспечивает удобный доступ к функциям для создания адресов, эмитации событий, имитации вызовов от имени других адресов (prank), а также управления временем и состоянием блокчейна.
Описание классов и функций
Контракт SymbioticDVNTest
Наследуется от Test из библиотеки forge-std. Основной класс, содержащий все тесты.
Поля класса
Имя | Тип | Описание |
|---|---|---|
| контракт | Экземпляр тестируемого контракта |
| адрес | Адрес администратора (создателя и управляющего). |
| адреса | Адреса трёх валидаторов, используемых в тестах. |
| адрес | Адрес обычного пользователя (не валидатора). |
| число | Приватные ключи валидаторов для генерации подписей. |
События
Тесты подписываются на события, которые эмитирует контракт SymbioticDVN. Они проверяют корректность вызовов:
MessageVerificationRequested— запрос на верификацию сообщения.ValidatorVerified— отдельный валидатор подтвердил сообщение.MessageVerified— достигнут кворум и сообщение верифицировано.
Методы
setUp()
Описание: Инициализация окружения перед выполнением тестов. Создаёт экземпляр контракта
SymbioticDVN, добавляет валидаторов и поддерживаемые цепочки.Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
Пример использования:
setUp();
// После вызова доступны валидаторы, контракт и поддерживаемые цепочки
testRequestVerification()
Описание: Тестирует функцию запроса верификации сообщения. Проверяет эмит события
MessageVerificationRequestedи правильность возвращаемого хеша сообщения.Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
Пример использования: запускается автоматически в тестовом фреймворке.
testVerifyMessage()
Описание: Проверяет корректность подтверждения сообщения валидатором с валидной подписью. Убеждается, что статус верификации обновляется, а счётчик валидаторов увеличивается.
Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testQuorumReached()
Описание: Проверяет сценарий достижения кворума валидаторов (в данном случае 2 из 3). Проверяет эмит события
MessageVerifiedи статус сообщенияVERIFIED.Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testInvalidSignature()
Описание: Проверяет, что при передаче неверной подписи (не соответствующей хешу сообщения) происходит revert с ошибкой
InvalidSignature.Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testUnsupportedChain()
Описание: Проверяет, что запрос верификации с указанием неподдерживаемой цепочки вызывает revert с ошибкой
InvalidChainId.Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testExpiredVerification()
Описание: Проверяет поведение при истечении таймаута верификации. После истечения времени попытка верифицировать сообщение вызывает revert с ошибкой
VerificationExpired. Статус сообщения меняется наEXPIRED.Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testAddRemoveValidator()
Описание: Проверяет добавление и удаление валидатора администратором. Проверяется состояние валидатора и общее количество валидаторов.
Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testUpdateQuorumThreshold()
Описание: Проверяет возможность изменения порога кворума (процент валидаторов, необходимый для подтверждения). Проверяется ограничение диапазона (от 1 до 10000, где 10000 = 100%).
Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testEmergencyVerifyMessage()
Описание: Проверяет функцию аварийной верификации сообщения администратором, которая сразу помечает сообщение как верифицированное без подписей валидаторов.
Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testPauseUnpause()
Описание: Проверяет работу механизма паузы контракта. При паузе вызовы
requestVerificationдолжны откатываться. После снятия паузы функция вновь доступна.Параметры: отсутствуют.
Возвращаемое значение: отсутствует.
testFuzzVerification(bytes32 messageHash, uint32 srcEid, uint32 dstEid)
Описание: Фаззинг тест для проверки верификации сообщений с произвольными хешами и идентификаторами цепочек. Добавляет цепочки в поддержку, если их нет, и проверяет корректность статуса.
Параметры:
messageHash— произвольный хеш сообщения (не равен 0).srcEid— идентификатор исходной цепочки (не равен 0).dstEid— идентификатор целевой цепочки (не равен 0).
Возвращаемое значение: отсутствует.
Важные детали реализации и алгоритмы
Валидация подписей: Валидаторы подписывают хеш сообщения, добавляя префикс Ethereum Signed Message, что соответствует стандарту EIP-191. Подписи проверяются на соответствие исходному сообщению.
Кворум: Для подтверждения сообщения необходимо собрать подписи не менее, чем 67% всех валидаторов (значение кворума можно менять). В тестах с 3 валидаторами это 2.
Таймаут верификации: Если верификация не завершается за отведённое время (
VERIFICATION_TIMEOUT), сообщение считается просроченным, и дальнейшие подтверждения не принимаются.Поддержка цепочек: Контракт поддерживает список chainIds, для которых разрешена верификация сообщений. Запросы с неподдерживаемых цепочек отклоняются.
Пауза: Контракт может быть приостановлен администратором, что блокирует вызовы основных функций.
Аварийная верификация: Администратор может принудительно пометить сообщение как верифицированное, минуя подписи валидаторов.
Взаимодействие с другими частями системы
SymbioticDVN.sol: Основной контракт с бизнес-логикой верификации сообщений. Этот файл тестирует именно его.
forge-std/Test.sol: Фреймворк для тестирования, предоставляющий виртуальную машину с возможностями эмуляции вызовов и управления состоянием.
Администратор и валидаторы: В тестах моделируются роли администратора и валидаторов с помощью приватных ключей и адресов.
Кроссчейн-сообщения: Используется структура
LayerZeroMessageиз контрактаSymbioticDVN, которая содержит информацию о сообщении, его хеше и цепочках источника и назначения.
Визуальная диаграмма — Структура класса SymbioticDVNTest
classDiagram
class SymbioticDVNTest {
+SymbioticDVN dvn
+address admin
+address validator1
+address validator2
+address validator3
+address user
+uint256 validator1Key
+uint256 validator2Key
+uint256 validator3Key
+setUp()
+testRequestVerification()
+testVerifyMessage()
+testQuorumReached()
+testInvalidSignature()
+testUnsupportedChain()
+testExpiredVerification()
+testAddRemoveValidator()
+testUpdateQuorumThreshold()
+testEmergencyVerifyMessage()
+testPauseUnpause()
+testFuzzVerification(bytes32,uint32,uint32)
}
SymbioticDVNTest ..> SymbioticDVN : использует
SymbioticDVNTest ..> Test : наследует
Пример использования некоторых тестов
Запрос верификации сообщения
function testRequestVerification() public {
SymbioticDVN.LayerZeroMessage memory message = SymbioticDVN.LayerZeroMessage({
messageHash: keccak256("test message"),
srcEid: 1,
dstEid: 137,
payloadHash: keccak256("test payload"),
confirmations: 12,
payload: "test payload"
});
bytes32 messageHash = dvn.requestVerification(message);
assertEq(messageHash, message.messageHash);
}
Проверка подписи валидатора
function testVerifyMessage() public {
bytes32 messageHash = dvn.requestVerification(message);
bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash));
(uint8 v, bytes32 r, bytes32 s) = vm.sign(validator1Key, ethSignedMessageHash);
bytes memory signature = abi.encodePacked(r, s, v);
vm.prank(validator1);
dvn.verifyMessage(messageHash, signature);
}
Заключение
Файл SymbioticDVN.t.sol — это тщательно проработанный набор модульных тестов, проверяющих ключевые аспекты работы кроссчейн-системы верификации сообщений. Он покрывает позитивные сценарии, обработку ошибок, управление ролями и экстренные ситуации. Тесты обеспечивают высокое качество и надёжность контракта SymbioticDVN, что критично для систем, работающих с межцепочечными коммуникациями и требующих высокой степени доверия.