Я потратил последние пару недель на изучение TLV-кодировщика в Rust: тип, длина, значение — старый приём для упаковки данных, чтобы они могли расширяться, не ломая старых читателей. Как-то я продумал это для Dusk — и причина наконец щёлкнула. Цепочка вроде @Dusk постоянно передаёт сообщения по сети: одноранговые узлы шепчутся, контракты вызываются, кошельки синхронизируются. Всё это нуждается в формате, который переживёт попытку добавить новое поле спустя два года.
Rust делает неприятную часть почти скучной — и в этом вся идея. Проверка границ. Отказ доверять байту длины, который заявляет, что прочитать нужно 4 ГБ.
Парсер, который паникует на мусорном вводе, — это парсер, который нельзя запускать в сети, где случайные байты появляются без приглашения. Я придерживаюсь обычных срезов &[u8], пропускаю копирование, пока оно действительно не понадобится, и опираюсь на enum для байта типа, чтобы компилятор поймал любой случай, который я забуду.
Не пропускайте уродливый код, который буквально двигает байты. Пишите его первым и пишите параноидально. От этого зависит всё остальное, что вы соберёте. #dusk
$DUSK
Rust делает неприятную часть почти скучной — и в этом вся идея. Проверка границ. Отказ доверять байту длины, который заявляет, что прочитать нужно 4 ГБ.
Парсер, который паникует на мусорном вводе, — это парсер, который нельзя запускать в сети, где случайные байты появляются без приглашения. Я придерживаюсь обычных срезов &[u8], пропускаю копирование, пока оно действительно не понадобится, и опираюсь на enum для байта типа, чтобы компилятор поймал любой случай, который я забуду.
Не пропускайте уродливый код, который буквально двигает байты. Пишите его первым и пишите параноидально. От этого зависит всё остальное, что вы соберёте. #dusk
$DUSK

