Сборочная среда и стенд для dicoop/blockchain (CoopOS / coopos nodeos).
Содержит две независимые части:
- Сборка мульти-стадийного образа
dicoop/blockchain:vX.Y.Zиз исходников~/cooposи~/cdt—Dockerfile+install.sh. - Стенд для локального запуска ноды и проверки совместимости версий —
docker-compose.yaml,config/,scripts/,Dockerfile.deb-runner.
.
├── Dockerfile # multi-stage build dicoop/blockchain (из ~/coopos)
├── install.sh # сборка + push dicoop/blockchain в Docker Hub
├── Dockerfile.deb-runner # ubuntu:22.04 + установленный coopos*.deb
├── docker-compose.yaml # параметризованный запуск ноды
├── .env.example # переменные для compose (image, tag, порты)
├── config/config.ini # лёгкая нода: seed p2p.coopenomics.world:9876
├── scripts/
│ ├── fetch-snapshot.sh # скачивает snapshot.coopenomics.world
│ ├── fetch-debs.sh # скачивает .deb с GitHub Releases coopenomics/coopos
│ ├── build-deb-image.sh # собирает coopos-deb:5.1.0 / 5.2.0 из .deb
│ ├── start.sh # старт ноды через compose (read-mode = sync с прода)
│ ├── stop.sh # стоп
│ ├── status.sh # head/version/chain_id через :8888 API
│ ├── test-compat.sh # snapshot-compat двух тегов dicoop/blockchain
│ ├── test-deb-compat.sh # миграционный тест .deb на одном data dir
│ ├── fork-snapshot.sh # форк прод-снапшота: to-json → jq-patch → from-json
│ └── start-fork.sh # writable fork: подменяет ключ eosio, продьюсит локально
├── config-fork/
│ └── config.ini # конфиг форкнутой ноды (без p2p, with producer + dev-key)
├── patches/
│ └── dev-fork.jq # JQ-патч: подмена ключа eosio в snapshot
├── snapshot.bin # gitignored
├── data/ # gitignored, файлы создаются root в контейнере
└── debs/ # gitignored
./scripts/start.sh --tag latest --from-snapshot --clean --follow--clean нужен потому что --snapshot применяется только при пустом data/. Чистит через одноразовый контейнер (файлы в data/ принадлежат root). --follow сразу хвостит логи.
После старта:
./scripts/status.sh # head_block_num, head_block_time, chain_id, server_version
./scripts/stop.sh # остановить (data/ сохраняется)API: http://127.0.0.1:8888 (HTTP), 9876 (P2P), 8088 → 8080 внутри (state-history). Порты переопределяются через NODE_HTTP_PORT / NODE_P2P_PORT / NODE_HISTORY_PORT в .env.
Симулирует продакшн-апгрейд: stop nodeos → dpkg -i новый.deb → start nodeos на том же data/. Если проходит — значит на проде апгрейд бесшовный, replay не нужен.
./scripts/fetch-debs.sh # требует gh CLI с auth, скачает оба .deb
./scripts/build-deb-image.sh # соберёт coopos-deb:5.1.0 и coopos-deb:5.2.0
./scripts/test-deb-compat.sh # OLD_TAG → NEW_TAG на одном data dirПараметры через env:
OLD_TAG=5.1.0 NEW_TAG=5.2.0— какие версии сравнивать (должны быть собраны черезbuild-deb-image.sh).MIN_BLOCKS=50— сколько блоков должно прирасти, чтобы признать прогресс.WAIT_SECONDS=180— таймаут на каждый этап.
Зелёный результат значит: можно делать dpkg -i на проде без двух нод и без replay.
Прод-снапшот содержит реальные ключи; чтобы локальная нода могла продьюсить и принимать write-транзакции, в снапшоте подменяется ключ eosio@owner|active (а в coopos он же — единственный активный продьюсер) на dev-ключ:
- public:
EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV - private:
5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
Требует leap-util snapshot from-json (есть начиная с тега v5.2.0+).
./scripts/start-fork.sh --clean --follow
# скрипт сам:
# - скачает snapshot.bin (если нет)
# - применит patches/dev-fork.jq → snapshot-fork.bin
# - стартанёт coopos-fork в изоляции от прод-сетиВнутри происходит: to-json | jq -f patches/dev-fork.jq | from-json → snapshot-fork.bin. Контейнер coopos-fork поднимается с config-fork/config.ini (без p2p-peer-address, с producer-name=eosio, signature-provider=…=KEY:…, enable-stale-production).
После старта — head_block_producer: eosio, блоки растут локально. Для cleos:
cleos wallet create --to-console
cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
cleos push action eosio updateauth '{...}' -p eosio@active # будет принятоfork-snapshot.sh — отдельный скрипт, можно вызывать самостоятельно, передавая свой JQ-патч через --patch <file>.
./scripts/test-compat.sh # OLD_TAG=v5.1.0-dev NEW_TAG=latestТест проверяет, что оба образа из реестра умеют поднять ноду из одного и того же продакшн-снапшота. Не путать с миграцией — здесь не проверяется hot-swap data dir между бинарниками.
COOPOS_SRC=~/coopos CDT_SRC=~/cdt ./install.sh # собирает + push на Docker HubТеги задаются константами в install.sh (VERSION_TAG, LATEST_TAG).
--image <name> dicoop/blockchain (default) | coopos-deb | …
--tag <tag> latest | v5.2.0 | 5.1.0 | …
--from-snapshot добавить --snapshot к nodeos (требует пустой data/)
--replay --replay-blockchain (только если в blocks.log есть genesis)
--hard-replay --hard-replay-blockchain
--clean предварительно удалить data/ (для применения снапшота)
--extra "<args>" произвольные доп.аргументы к nodeos
--follow / -f tail логов после старта
content of memory does not match data expected by executableпри переключении бинарника — почти всегда означает разный toolchain (gcc/boost) у двух сборок, а не код. Pre-builtdicoop/blockchain:v5.1.0-dev(2024-04-16) с современнымlatestнесовместим именно поэтому. Собирать сравниваемые версии одним и тем же CI/Dockerfile.Genesis state is necessary…при--replay-blockchain— вblocks.logнет genesis, потому что нода стартовала со снапшота. Replay в этом случае невозможен; либо снапшот, либо blocks.log с genesis.Permission deniedприrm -rf data/— файлы создаёт root в контейнере.start.sh --cleanчистит через одноразовый контейнер от того же образа.- Порт
8080занят — на хосте обычно крутится nocodb или другой сервис. Дефолт state-history наружу =8088. gh release downloadдля draft-релиза — работает только еслиgh authпривязан к аккаунту с доступом к draft.
~/.claude/projects/-home-admin/memory/project_coopos_migration.md — что выяснилось про совместимость chainbase shared_memory, какой апгрейд бесшовный, когда нужен snapshot-перенакат.