Skip to content

Commit 2c5d862

Browse files
authored
Merge pull request #112 from VIZ-Blockchain/snapshot-fix
fix(snapshot): detect and recover validator vote snapshot inconsisten…
2 parents 9ac4096 + b5b10b1 commit 2c5d862

52 files changed

Lines changed: 2342 additions & 607 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.qoder/docs/jsonrpc-api-spec.json‎

Lines changed: 1353 additions & 0 deletions
Large diffs are not rendered by default.

‎@l10n/ru/docs/development/building.md‎

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@ chmod +x build-linux.sh
2626

2727
```bash
2828
./build-linux.sh # Release-сборка (по умолчанию)
29-
./build-linux.sh -l # LOW_MEMORY_NODE (узлы-валидаторы)
3029
./build-linux.sh -n # Testnet-сборка
3130
./build-linux.sh -t Debug -j4 # Debug-сборка с 4 параллельными задачами
32-
./build-linux.sh --skip-deps # Пропустить установку зависимостей
3331
./build-linux.sh --install # Установить в систему после сборки
3432

3533
# Пользовательские пути к зависимостям
@@ -54,7 +52,6 @@ chmod +x build-mac.sh
5452
**Параметры:**
5553

5654
```bash
57-
./build-mac.sh -l # Low-memory узел
5855
./build-mac.sh -n # Testnet
5956
./build-mac.sh --skip-deps # Пропустить установки Homebrew
6057
./build-mac.sh --boost-root /opt/boost_1_74_0
@@ -77,7 +74,6 @@ build-mingw.bat
7774
| Переменная | По умолчанию | Описание |
7875
|-----------|-------------|---------|
7976
| `VIZ_BUILD_TYPE` | Release | Release или Debug |
80-
| `VIZ_LOW_MEMORY` | OFF | Включить low-memory узел |
8177
| `VIZ_BUILD_TESTNET` | OFF | Testnet-сборка |
8278
| `VIZ_FULL_STATIC` | OFF | Полностью статический бинарник |
8379
| `VIZ_CMAKE_EXTRA` | — | Дополнительные флаги CMake |
@@ -100,7 +96,6 @@ build-msvc.bat
10096
|-----------|-------------|---------|
10197
| `VIZ_VS_VERSION` | "Visual Studio 17 2022" | Генератор Visual Studio |
10298
| `VIZ_BUILD_TYPE` | Release | Тип сборки |
103-
| `VIZ_LOW_MEMORY` | OFF | Low-memory узел |
10499
| `VIZ_BUILD_TESTNET` | OFF | Testnet-сборка |
105100

106101
**Требования:** Visual Studio 2019+ с нагрузкой "Desktop development with C++", CMake 3.16+.
@@ -125,7 +120,6 @@ build-msvc.bat
125120
| Параметр | По умолчанию | Описание |
126121
|---------|-------------|---------|
127122
| `BUILD_TESTNET` | OFF | Сборка для testnet |
128-
| `LOW_MEMORY_NODE` | OFF | Исключить неконсенсусные данные (уменьшает RAM) |
129123
| `CHAINBASE_CHECK_LOCKING` | OFF | Включить проверку блокировок (только для разработки) |
130124
| `BUILD_SHARED_LIBRARIES` | OFF | Собирать разделяемые библиотеки |
131125
| `USE_PCH` | OFF | Включить предкомпилированные заголовки (ускоряет пересборку) |
@@ -140,9 +134,6 @@ build-msvc.bat
140134
# Release-сборка
141135
python3 programs/build_helpers/configure_build.py --release --src ../..
142136

143-
# Debug с low-memory
144-
python3 programs/build_helpers/configure_build.py --debug --low-memory
145-
146137
# Кросс-компиляция для Windows с MinGW
147138
python3 programs/build_helpers/configure_build.py --win --release
148139

‎@l10n/ru/docs/node/building.md‎

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ chmod +x build-linux.sh
4646
### Основные флаги сборки
4747

4848
```bash
49-
# Низкопамятный узел (для валидаторов/сид-узлов — без плагинов индексирования истории)
50-
./build-linux.sh -l
51-
5249
# Сборка для тестнета
5350
./build-linux.sh -n
5451

@@ -58,9 +55,6 @@ chmod +x build-linux.sh
5855
# Параллельные задания
5956
./build-linux.sh -j 8
6057

61-
# Пропустить установку зависимостей (уже установлены)
62-
./build-linux.sh --skip-deps
63-
6458
# Пользовательские пути к Boost / OpenSSL
6559
./build-linux.sh --boost-root /opt/boost_1_74_0 --openssl-root /opt/openssl
6660
```
@@ -99,7 +93,6 @@ build-mingw.bat
9993
| Переменная | По умолчанию | Описание |
10094
|------------|--------------|----------|
10195
| `VIZ_BUILD_TYPE` | `Release` | `Release` или `Debug` |
102-
| `VIZ_LOW_MEMORY` | `OFF` | `ON` для низкопамятного узла |
10396
| `VIZ_BUILD_TESTNET` | `OFF` | `ON` для сборки тестнета |
10497
| `VIZ_FULL_STATIC` | `OFF` | `ON` для полностью статического бинарного файла |
10598

@@ -124,7 +117,6 @@ build-msvc.bat
124117
| Опция | По умолчанию | Описание |
125118
|-------|--------------|----------|
126119
| `BUILD_TESTNET` | `OFF` | Включить код для тестнета |
127-
| `LOW_MEMORY_NODE` | `OFF` | Исключить плагины истории/индексирования |
128120
| `CHAINBASE_CHECK_LOCKING` | `OFF` | Включить проверки блокировок (debug) |
129121
| `BUILD_SHARED_LIBRARIES` | `OFF` | Собрать разделяемые библиотеки |
130122
| `USE_PCH` | `OFF` | Включить предкомпилированные заголовки (ускоряет пересборку) |
@@ -134,7 +126,6 @@ build-msvc.bat
134126
```bash
135127
mkdir build && cd build
136128
cmake -DCMAKE_BUILD_TYPE=Release \
137-
-DLOW_MEMORY_NODE=ON \
138129
-DCMAKE_INSTALL_PREFIX=/usr/local \
139130
..
140131
make -j$(nproc)

‎@l10n/ru/docs/node/docker.md‎

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ docker build \
129129

130130
### CMake-флаги для каждого образа
131131

132-
| Образ | `LOW_MEMORY_NODE` | `BUILD_TESTNET` |
133-
|-------|:-----------------:|:---------------:|
134-
| production | OFF | OFF |
135-
| testnet | OFF | ON |
132+
| Образ | `BUILD_TESTNET` |
133+
|-------|:---------------:|
134+
| production | OFF |
135+
| testnet | ON |
136136

137137
---
138138

@@ -167,6 +167,59 @@ shared-file-size = 4G
167167

168168
---
169169

170+
## Ротация логов
171+
172+
vizd пишет весь вывод в stdout/stderr. Дефолтный драйвер `json-file` в Docker **не имеет ограничений по размеру** — цикл краша или буря ошибок может заполнить диск хоста за считанные минуты (в продакшне наблюдалось 35 ГБ+).
173+
174+
Вместо этого используйте драйвер `local`. Он хранит логи в компактном бинарном формате и автоматически ротирует файлы.
175+
176+
**Глобальная конфигурация (рекомендуется — защищает все контейнеры на хосте):**
177+
178+
```json
179+
// /etc/docker/daemon.json
180+
{
181+
"log-driver": "local",
182+
"log-opts": {
183+
"max-size": "100m",
184+
"max-file": "5"
185+
}
186+
}
187+
```
188+
189+
Применить:
190+
191+
```bash
192+
sudo systemctl restart docker
193+
```
194+
195+
**Для конкретного контейнера (`docker run`):**
196+
197+
```bash
198+
docker run -d \
199+
--log-driver=local \
200+
--log-opt max-size=100m \
201+
--log-opt max-file=5 \
202+
--name vizd \
203+
vizblockchain/vizd:latest
204+
```
205+
206+
**Для конкретного контейнера (docker-compose):**
207+
208+
```yaml
209+
services:
210+
vizd:
211+
image: vizblockchain/vizd:latest
212+
logging:
213+
driver: local
214+
options:
215+
max-size: "100m"
216+
max-file: "5"
217+
```
218+
219+
> При `max-file: 5` и `max-size: 100m` Docker хранит не более 500 МБ логов на контейнер и автоматически удаляет старейший файл при ротации.
220+
221+
---
222+
170223
## Устранение неполадок
171224

172225
| Симптом | Причина | Решение |
@@ -176,3 +229,4 @@ shared-file-size = 4G
176229
| Нет пиров | Файрвол блокирует порт 2001 | Откройте порт 2001 TCP входящий |
177230
| Медленная синхронизация | Снимок не загружен | Предоставьте снимок в томе перед первым запуском |
178231
| `Permission denied` на `/var/lib/vizd` | Несоответствие владельца тома | `chown -R 1000:1000 /data/vizd` |
232+
| Диск заполняется логами Docker | Драйвер `json-file` не имеет ограничения по размеру | Настройте драйвер `local` с `max-size`/`max-file` — см. [Ротация логов](#ротация-логов) |

‎@l10n/ru/docs/node/getting-started.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ shared-file-size = 4G
133133

134134
# Плагины (полный узел)
135135
plugin = chain p2p webserver json_rpc database_api network_broadcast_api
136-
plugin = social_network tags follow account_history
136+
plugin = account_history
137137
```
138138

139139
Для узла-валидатора см. [Узел-валидатор](./validator-node.md).
@@ -172,7 +172,6 @@ curl -s -X POST http://localhost:8090 \
172172
| Полный узел | `config.ini` | Все плагины, публичные RPC-эндпоинты |
173173
| Валидатор | `config_witness.ini` | Производство блоков, RPC только на localhost |
174174
| Тестовая сеть | `config_testnet.ini` | Разработка и тестирование |
175-
| Малая память | `config.ini` + флаг сборки `LOW_MEMORY_NODE` | Только консенсус, без индексов истории |
176175

177176
---
178177

‎@l10n/ru/docs/plugins/overview.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,24 @@ DLT P2P-сетевое взаимодействие — распростране
222222
- `track-account-range` — диапазон имён аккаунтов для индексирования (по умолчанию: все аккаунты)
223223
- `history-count-blocks` — сохранять историю за N блоков
224224

225+
> **Зависимость:** `account_history` **требует** `operation_history` как родительский плагин
226+
> (`APPBASE_PLUGIN_REQUIRES`). Нода не запустится при отсутствии `operation_history`.
227+
> `account_history` хранит ссылки `operation_id_type` (внешние ключи) на строки `operation_object`,
228+
> которыми управляет `operation_history`; при запросе `get_account_history` разрешает их через
229+
> `database.get(itr->op)`.
230+
>
231+
> **Всегда включать оба плагина вместе:**
232+
> ```ini
233+
> plugin = operation_history
234+
> plugin = account_history
235+
> ```
236+
>
237+
> **Координация очистки:** Оба плагина читают один и тот же ключ `history-count-blocks` из
238+
> `config.ini` — разделения по плагинам нет. Одно значение применяется к обоим одновременно.
239+
> Внутри `account_history` дополнительно вызывает `operation_history::get_min_keep_block()`
240+
> при каждом блоке как защитную проверку, гарантируя, что его записи никогда не будут ссылаться
241+
> на уже удалённый `operation_object`.
242+
225243
---
226244
227245
### `operation_history`

‎@l10n/ru/docs/plugins/webserver.md‎

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -137,22 +137,6 @@ server {
137137
}
138138
139139
location / {
140-
# CORS — разрешить любой источник (публичный API)
141-
add_header 'Access-Control-Allow-Origin' '*' always;
142-
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
143-
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
144-
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
145-
146-
if ($request_method = 'OPTIONS') {
147-
add_header 'Access-Control-Allow-Origin' '*' always;
148-
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
149-
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
150-
add_header 'Access-Control-Max-Age' 1728000;
151-
add_header 'Content-Type' 'text/plain charset=UTF-8';
152-
add_header 'Content-Length' 0;
153-
return 204;
154-
}
155-
156140
proxy_pass http://127.0.0.1:8090;
157141
proxy_http_version 1.1;
158142

‎@l10n/ru/docs/storage/shared-memory.md‎

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,21 @@ skip-virtual-ops = true
9292

9393
База данных автоматически увеличивается, когда свободное место падает ниже `min-free-shared-file-size`. При каждом изменении размера:
9494

95-
1. Приостанавливаются все операции (включая производство блоков и API-запросы).
96-
2. Уничтожается текущее отображение памяти.
97-
3. Файл увеличивается на `inc-shared-file-size`.
98-
4. Файл заново отображается, пересчитываются все указатели индексов.
95+
1. Записывается маркер сбоя `resize_in_progress`.
96+
2. Все грязные страницы сбрасываются на диск (`flush()`).
97+
3. Приостанавливаются все операции (включая производство блоков и API-запросы).
98+
4. Уничтожается текущее отображение памяти.
99+
5. Файл увеличивается на `inc-shared-file-size`.
100+
6. Файл заново отображается, пересчитываются все указатели индексов.
101+
7. Проверяется, что ключевые объекты (например, `dynamic_global_property_object`) пережили перераспределение.
102+
8. Маркер сбоя удаляется.
103+
104+
### Механизмы безопасности
105+
106+
- **Сброс перед изменением размера:** Грязные страницы записываются на диск до уничтожения отображения, что гарантирует согласованность файла на диске в случае сбоя во время увеличения.
107+
- **Маркер сбоя:** Файл `resize_in_progress` записывается перед деструктивным перераспределением и удаляется после успешного завершения. Если процесс аварийно завершается во время изменения размера, маркер сохраняется и запускает автоматическое восстановление при следующем запуске.
108+
- **Проверка после изменения размера:** После перераспределения узел проверяет, что `max_memory()` соответствует ожидаемому размеру и что критические объекты (например, `dynamic_global_property_object`) не повреждены. Повреждение обнаруживается рано, а не приводит к запутанным сбоям позже.
109+
- **Безопасность при bad_alloc:** Если разделяемая память исчерпана во время применения блока, сессия отмены безопасно отбрасывается (вместо попытки обречённой отмены, которая привела бы к краху процесса через `std::terminate`). Отложенное изменение размера планируется на следующий блок.
99110

100111
Выделяйте `shared-file-size` с запасом, чтобы минимизировать частоту изменений размера. Каждое изменение вызывает скачок задержки.
101112

@@ -121,22 +132,25 @@ skip-virtual-ops = true
121132
```
122133
1. Открыть shared_memory.bin (увеличить, если shared-file-size больше)
123134
2. Захватить эксклюзивную блокировку файла
124-
3. Инициализировать индексы
125-
4. Если отсутствует genesis → init_genesis()
126-
5. Открыть block_log или dlt_block_log
127-
6. undo_all() → откатиться к последнему необратимому блоку
128-
7. Проверить совпадение head блока с block log
135+
3. Проверить маркер сбоя resize_in_progress → запустить восстановление при обнаружении
136+
4. Инициализировать индексы
137+
5. Если отсутствует genesis → init_genesis()
138+
6. Открыть block_log или dlt_block_log
139+
7. undo_all() → откатиться к последнему необратимому блоку
140+
8. Проверить совпадение head блока с block log
129141
```
130142

131143
---
132144

133145
## Восстановление
134146

135147
| Симптом | Действие |
136-
|---------|---------|
148+
|---------|--------|
137149
| `CRITICAL: validator X account object MISSING` | Повреждение — использовать `--replay-from-snapshot --snapshot-auto-latest` |
138150
| `Could not modify object, uniqueness constraint violated` | Повреждение — использовать `--replay-from-snapshot --snapshot-auto-latest` |
139151
| `Unable to acquire READ lock` | Конкуренция за блокировку — увеличить `read-wait-micro` / включить `single-write-thread` |
152+
| `Shared memory corrupted: previous resize() crashed` | Прерванное изменение размера — использовать `--replay-from-snapshot --snapshot-auto-latest` |
153+
| `dynamic_global_property_object missing after resize` | Повреждение после изменения размера — использовать `--replay-from-snapshot --snapshot-auto-latest` |
140154
| Узел зацикливается при запуске | Повреждённый файл — `--replay-from-snapshot --snapshot-auto-latest` |
141155

142156
Варианты восстановления:

‎@l10n/zh-CN/docs/development/building.md‎

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@ chmod +x build-linux.sh
2626

2727
```bash
2828
./build-linux.sh # Release 构建(默认)
29-
./build-linux.sh -l # LOW_MEMORY_NODE(验证者节点)
3029
./build-linux.sh -n # Testnet 构建
3130
./build-linux.sh -t Debug -j4 # Debug 构建,4 个并行任务
32-
./build-linux.sh --skip-deps # 跳过依赖安装
3331
./build-linux.sh --install # 构建后安装到系统
3432

3533
# 自定义依赖路径
@@ -54,7 +52,6 @@ chmod +x build-mac.sh
5452
**选项:**
5553

5654
```bash
57-
./build-mac.sh -l # 低内存节点
5855
./build-mac.sh -n # Testnet
5956
./build-mac.sh --skip-deps # 跳过 Homebrew 安装
6057
./build-mac.sh --boost-root /opt/boost_1_74_0
@@ -77,7 +74,6 @@ build-mingw.bat
7774
| 变量 | 默认值 | 描述 |
7875
|------|--------|------|
7976
| `VIZ_BUILD_TYPE` | Release | Release 或 Debug |
80-
| `VIZ_LOW_MEMORY` | OFF | 启用低内存节点 |
8177
| `VIZ_BUILD_TESTNET` | OFF | Testnet 构建 |
8278
| `VIZ_FULL_STATIC` | OFF | 完全静态二进制文件 |
8379
| `VIZ_CMAKE_EXTRA` | — | 附加 CMake 标志 |
@@ -100,7 +96,6 @@ build-msvc.bat
10096
|------|--------|------|
10197
| `VIZ_VS_VERSION` | "Visual Studio 17 2022" | Visual Studio 生成器 |
10298
| `VIZ_BUILD_TYPE` | Release | 构建类型 |
103-
| `VIZ_LOW_MEMORY` | OFF | 低内存节点 |
10499
| `VIZ_BUILD_TESTNET` | OFF | Testnet 构建 |
105100

106101
**要求:** Visual Studio 2019+(带"Desktop development with C++"工作负载)、CMake 3.16+。
@@ -125,7 +120,6 @@ build-msvc.bat
125120
| 选项 | 默认值 | 描述 |
126121
|------|--------|------|
127122
| `BUILD_TESTNET` | OFF | 为 testnet 构建 |
128-
| `LOW_MEMORY_NODE` | OFF | 排除非共识数据(减少 RAM) |
129123
| `CHAINBASE_CHECK_LOCKING` | OFF | 启用锁检查(仅用于开发) |
130124
| `BUILD_SHARED_LIBRARIES` | OFF | 构建共享库 |
131125
| `USE_PCH` | OFF | 启用预编译头文件(加速重新构建) |
@@ -140,9 +134,6 @@ build-msvc.bat
140134
# Release 构建
141135
python3 programs/build_helpers/configure_build.py --release --src ../..
142136

143-
# 带低内存的 Debug
144-
python3 programs/build_helpers/configure_build.py --debug --low-memory
145-
146137
# 使用 MinGW 交叉编译 Windows 版本
147138
python3 programs/build_helpers/configure_build.py --win --release
148139

0 commit comments

Comments
 (0)