☰
quip-validator 版本发布全流程实战指南:从 pre-tag 验证、SemVer 标签到镜像发布与 testnet 冒烟测试
2026/10/12 1:19:38 网站建设 项目流程

【免费下载链接】quip-validator

A rust implementation of the Quip Protocol forked from Substrate

项目地址:https://gitcode.com/gh_mirrors/qu/quip-validator
点击查看免费下载

本文以仓库 docs/release.md 为骨架,结合.gitlab-ci.yml、Dockerfile、chain-spec 与密钥生成脚本的源码实现,完整还原 Quip 协议验证者节点(quip-network-node)从"发布候选"到"镜像上架"的全过程。读完本文,你将掌握 quip-validator 的标准发布清单(Release Checklist)、跨仓库统一的 SemVer 标签规范、浮动标签(floating tag)解析规则、双镜像发布与冒烟验证流程,以及 v0.2.0 首个 SemVer 版本所承载的测试网身份与配套工具链。

一、release.md 在仓库中的定位

docs/release.md是 quip-validator 的版本发布操作清单,篇幅不长但信息密度极高:它定义了打标签前的质量门槛、打标签命令与版本号格式、打标签后的 CI 与镜像验证,以及 v0.2.0 这个关键里程碑的发布内容说明。与仓库内其他文档(如 docs/testnet-keys.md 的密钥生成流程、docs/genesis-quip-testnet.md 的创世清单)一起,构成了发布测试网版本所需的完整运维手册。

从源码结构看,quip-validator 是一个基于 Substrate 的 Rust 实现(工作区配置见 Cargo.toml),节点二进制名为quip-network-node(工作区成员 node/,入口为 node/src/main.rs)。其发布产物是两个容器镜像:验证者节点镜像与 EVM sidecar 镜像,均由 GitLab CI 在 release tag 上触发构建并推送到容器注册表。整个发布流程可以概括为三个阶段:

  1. Pre-tag verification:所有质量检查在本地或分支管道完成;
  2. Tag:在选定的分支上打 SemVer 标签并推送,CI 据此发布镜像;
  3. Post-tag verification:验证 CI 全绿、镜像可拉取、sidecar 可运行、节点能发现测试网 bootnode。

二、Pre-tag verification:打标签前的质量门槛

发布前必须逐条核对以下清单,任何一项失败都意味着版本还不能发布:

检查项命令 / 操作说明与源码依据
合并目标版本提交所有目标提交通过 MR 合并进main发布基于干净的main(或维护分支)进行
全量编译检查cargo check --workspace --all-targets覆盖全部工作区成员;transaction-crypto-py(PyO3 cdylib)被显式排除在工作区之外(见 Cargo.toml),不会扰动 node/runtime 构建
Clippy 门禁cargo clippy --workspace --all-targets -- -D warnings仓库在 Cargo.toml 中配置了细粒度的 lints 白名单,correctness/complexity保持 warn
全量测试cargo test --workspace包含 runtime genesis preset 构建测试与链上冒烟测试
节点镜像本地构建docker build -t quip-network-node:rc .对应根目录 Dockerfile:Rust 1.95.0 固定工具链、wasm32v1-none目标、SSH→HTTPS 依赖重写
Sidecar 静态构建检查docker build --check -f docker/revive-eth-rpc.Dockerfile .docker/revive-eth-rpc.Dockerfile 从固定 commit(f17113ffe…)的QuipNetwork/polkadot-sdk构建eth-rpc二进制
版本号自检./target/release/quip-network-node --version版本串来自SUBSTRATE_CLI_IMPL_VERSION,其中嵌入 git commit hash(见 Dockerfile 的SUBSTRATE_CLI_GIT_COMMIT_HASHbuild-arg 说明)
Chain spec 原始导出./target/release/quip-network-node export-chain-spec --chain quip-testnet --raw > /tmp/quip-testnet.raw.json对应 node/src/chain_spec.rs 的quip_testnet_chain_spec();--raw展开所有 genesis 字段,供下游发布
配套仓库 MRnodes.quip.network仓库合入匹配的chain-specs/aglais-network.json(sha256 与上述 raw 导出一致)托管 JSON 是长期事实来源(source of truth),二进制内 preset 仅用于审计与复现

几点源码级说明:

  • 为何必须用export-chain-spec而不是build-spec:在 node/src/cli.rs 中build-spec已被标记为 deprecated(将在 2026/04/01 后移除),官方推荐使用export-chain-spec。发布脚本应直接使用新命令,避免将来失效。
  • --chain quip-testnet从哪里来:quip_testnet_chain_spec()通过with_id("quip_testnet")、with_chain_type(ChainType::Live)定义链身份,协议 ID 为agls-network,并内置三个 bootnode 的 multiaddr(/dns4/bootnode-N.aglais.quip.network/tcp/30333/p2p/12D3KooW…)。该 preset 在 runtime 侧由QUIP_TESTNET_RUNTIME_PRESET(见 runtime/src/genesis_config_presets.rs)注册,raw 导出即nodes.quip.network发布的aglais-network.json。
  • sidecar 静态检查为什么能"静态":docker build --check只做 Dockerfile 解析与上下文校验,不实际执行构建,用于在推送分支前快速发现 Dockerfile 语法/上下文错误;完整的 eth-rpc 构建发生在真正的 release 管道中。

三、Tag:打标签与 SemVer 版本号规范

3.1 打标签命令

git checkout <release-branch> # main 或活跃系列分支(如 v0.2)——这个选择决定浮动标签 git pull # 见下方"浮动标签"说明 git tag -a v<MAJOR>.<MINOR>.<PATCH> -m "v<MAJOR>.<MINOR>.<PATCH>: <one-line summary>" git push origin v<MAJOR>.<MINOR>.<PATCH>

要点:

  • 必须使用 annotated tag(-a),携带 tag message 便于审计;
  • 分支选择直接影响浮动标签:在v0.2分支上打的标签发布:<tag>+:v0.2,在main上打的标签发布:<tag>+:latest,两者都会额外附带:sha-<short-sha>;若标签既不从main可达也不从任何系列分支可达,则只发布:<tag>+:sha-<short-sha>。

3.2 CI 如何拾取标签并发布镜像

GitLab CI 管道通过$CI_COMMIT_TAG规则识别 release tag(对应 .gitlab-ci.yml 中的.publish-rules),仅 release tag 会构建并推送镜像——分支推送永远不会发布镜像。发布产物为两个多架构镜像:

  • registry.gitlab.com/quip.network/quip-validator/quip-network-node:v<MAJOR>.<MINOR>.<PATCH>
  • registry.gitlab.com/quip.network/quip-validator/quip-network-evm-sidecar:v<MAJOR>.<MINOR>.<PATCH>

(容器注册表路径与 Cargo.toml 中声明的仓库地址gitlab.com/quip.network/quip-validator.git一致。)

3.3 版本标签格式:跨仓库统一标准

预发布标签必须使用SemVer 连字符预发布格式:

  • ✅v0.2.1-rc18
  • ❌v0.2.1rc18(PEP 440 无连字符形式,严禁使用)

这是跨仓库标准,目的是让quip-node-manager等任何 SemVer 消费者能正确排序发布候选(rc 按数字递增)。完整的理由说明见quip-protocol仓库的docs/VERSIONING.md(本仓库未收录该文件,此处仅作关联提及)。

3.4 浮动标签(floating tag)的解析逻辑

由于tag 管道不携带 branch 变量,浮动标签必须通过 commit 祖先关系(ancestry)解析。这一逻辑在 .gitlab-ci.yml 的resolve-floating-tag作业中实现:

- git fetch origin main - | FLOATING_TAGS="" if git merge-base --is-ancestor "$CI_COMMIT_SHA" origin/main; then if printf '%s' "$CI_COMMIT_TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then minor=$(printf '%s' "$CI_COMMIT_TAG" | sed -E 's/^(v[0-9]+\.[0-9]+).*/\1/') FLOATING_TAGS="latest ${minor} stable beta" elif printf '%s' "$CI_COMMIT_TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+$'; then FLOATING_TAGS="beta" fi fi

实际解析规则可以归纳为下表:

标签类型提交是否可从main到达浮动标签
稳定版v0.2.1是latest、v0.2、stable、beta
稳定版v0.2.1否(维护分支)无(只发布:<tag>+:sha-<short-sha>)
RC 版v0.2.1-rc18是beta
RC 版否无

随后.manifest-publish作业(.gitlab-ci.yml)用manifest-tool把 amd64/arm64 两个架构镜像合并为多架构 manifest,并一次性打上PRIMARY_TAG(release tag)、sha-<short-sha>以及resolve-floating-tag解析出的浮动标签。注意 CI 采用GIT_DEPTH: 0全量克隆——merge-base需要真实的完整祖先链,浅克隆无法正确判定。

stable/beta通道之所以只允许"main 祖先"的标签移动,是为了防止在旧维护分支上打标签把通道向后拨(a release is newer than every rc before it,但旧分支的新标签不一定比 main 上的版本新)。

四、Post-tag verification:打标签后的发布验证

标签推送后,需要按以下顺序逐项确认发布成功:

4.1 CI 管道全绿

glab ci status --live

使用 GitLab CLI 的--live参数实时跟踪管道状态,直到所有作业结束。

4.2 两个镜像均已上架

docker pull registry.gitlab.com/quip.network/quip-validator/quip-network-node:v<MAJOR>.<MINOR>.<PATCH> docker pull registry.gitlab.com/quip.network/quip-validator/quip-network-evm-sidecar:v<MAJOR>.<MINOR>.<PATCH>

4.3 Sidecar 镜像可启动并输出 CLI help

docker run --rm \ registry.gitlab.com/quip.network/quip-validator/quip-network-evm-sidecar:v<MAJOR>.<MINOR>.<PATCH> \ --help

这与 docker/revive-eth-rpc.Dockerfile 的运行时配置一致:ENTRYPOINT ["/usr/local/bin/eth-rpc"]+CMD ["--help"],即该镜像默认动作就是打印 CLI 帮助;容器以非 root 用户eth-rpc(uid 1001)运行。

4.4 对已发布 spec 做冒烟测试

curl -fsSL https://gitlab.com/quip.network/nodes.quip.network/-/raw/main/chain-specs/aglais-network.json \ -o /tmp/aglais-network.json docker run --rm -v /tmp:/spec \ registry.gitlab.com/quip.network/quip-validator/quip-network-node:v<MAJOR>.<MINOR>.<PATCH> \ --chain=/spec/aglais-network.json --tmp --name v-smoke --no-mdns

预期结果:60 秒内发现三个规范 bootnode 中至少一个。

这条命令的每个参数都有明确目的:

  • --chain=/spec/aglais-network.json:使用刚发布的aglais-network.json(而非二进制内嵌 preset)作为链配置——这正是验证"托管 spec 与发布镜像配套"的关键一步;
  • --tmp:使用临时数据库目录,容器退出后不留状态;
  • --name v-smoke:节点身份,便于日志识别;
  • --no-mdns:关闭本地 mDNS 发现,确保 peer 发现完全依赖 spec 中的 bootnode 列表。

五、v0.2.0 发布内容解读

docs/release.md明确列出了 v0.2.0(该文档对应的首个 SemVer 版本)的核心内容:

5.1 首个 SemVer 标签

此前验证者镜像只发布:latest和:sha-<short>;v0.2.0 起启用v<MAJOR>.<MINOR>.<PATCH>语义化版本标签,为下游(如quip-node-manager)提供了可排序、可预期的版本通道。

5.2 内置 quip-testnet 链规格

v0.2.0 首次在二进制内置quip-testnet链规格 preset:三个 operator 控制的 bootnode +ChainType::Live创世。其实现细节:

  • 节点侧 node/src/chain_spec.rs:ChainSpec::builder(...).with_id("quip_testnet").with_chain_type(ChainType::Live).with_protocol_id("agls-network"),并写入三个 bootnode multiaddr 与 token 属性(AGLS、12 位小数、ss58Format=42);
  • runtime 侧 runtime/src/genesis_config_presets.rs:quip_testnet_config_genesis()通过include_str!加载 runtime/src/genesis_quip_testnet/ 下六个 hex 文件(每个 operator 的 BABE/GRANDPA 公钥),配合内联的tx_account_from_hex(...)字面量钉死三个 operator 的交易账户;
  • 创世配置中每个 authority 是(account, babe, grandpa)三元组(account 同时作为 validator stash 与 controller,v0.2 未接入 staking,因此这样可行),sudo 由 operator 1 持有,quantum_compute_mempool的default_ising_spec_builder也指向 operator 1(见testnet_genesis函数)。

三种本地 preset(development / local / local_three_validator)与 quip-testnet preset 一起,通过get_preset/preset_names注册进 runtime 的 genesis builder,且均有对应的 storage 构建测试(*_preset_builds系列,验证 BABE/GRANDPA authority 不会被pallet-session与pallet-babe双重初始化而 panic)。

5.3 密钥生成辅助脚本与示例

  • scripts/derive-operator-keys.sh:一键完成单个 bootnode operator 的密钥生成——BIP39 mnemonic(key generate)、libp2p node-key(key generate-node-key --file,并用key inspect-node-key可靠回收 peer-id)、以及混合 BABE/GRANDPA/TX 公钥推导;密钥以0600权限落盘并写入quip-testnet-keys/(目录内置*的.gitignore防误提交),公共 bundle 打印到 stdout 并保存为public-bundle.txt供回传发布协调人;
  • crates/transaction-crypto/examples/derive_genesis_keys.rs:从单一 seed URI 派生混合签名公钥——sr25519_fndsa512(H4,用于 BABE 与交易账户)与ed25519_fndsa512(H2,用于 GRANDPA),输出babe_pub/grandpa_pub/tx_account_ss58/tx_account_hex,其中tx_account由account_id_from_public(&babe_pub)派生,因此只需一个 mnemonic 即可生成全部三套密钥材料。

完整的 operator 流程(含 Runtime 117 H2/H4 链重建重启后的insert-hybrid-key命令)记录在 docs/testnet-keys.md,operator 公共清单见 docs/genesis-quip-testnet.md。

5.4 macOS rpath 修复

新增 macOS 专属的.cargo/config.tomlrpath 配置:librocksdb-sys的 bindgen 构建脚本在 macOS 上找不到@rpath/libclang.dylib(Xcode / CommandLineTools 的 libclang 都只有 rpath 安装名,而clang-sys只生成了链接搜索路径),导致全新 Xcode 安装下cargo build失败。修复方式是在[target.'cfg(target_os = "macos")']下为每次 rustc 调用追加两个标准 libclang 位置的-Wl,-rpath,从而无需手动导出LIBCLANG_PATH。

5.5 Runtime spec_version 说明

v0.2.0 时 runtimespec_version保持101——该版本是打包 + 测试网身份,而非 runtime 升级。需要说明的是:截至当前仓库源码,runtime/src/lib.rs 中的spec_version已演进到118(transaction_version: 7),期间经历了 Runtime 117 的 H4/H2 FN-DSA-512 链重建重启(见 docs/genesis-quip-testnet.md,旧状态被丢弃、以 929 字节共识权威密钥重新创世)。因此若以本文流程发布新版本,请以发布时仓库实际的spec_version为准,并遵循"runtime 变更 → 需 bump spec_version → 属于 runtime 升级"与"纯打包/运维变更 → spec_version 不变"的区分原则。

六、发布流程与仓库其他模块的衔接

发布流程并非孤立存在,它与仓库内多个模块形成闭环:

发布步骤关联仓库证据
镜像构建Dockerfile(node)、docker/revive-eth-rpc.Dockerfile(sidecar)
CI 发布.gitlab-ci.yml(.publish-rules、resolve-floating-tag、.manifest-publish)
Chain spec 导出node/src/chain_spec.rs、node/src/cli.rs(export-chain-spec)
创世 presetruntime/src/genesis_config_presets.rs、runtime/src/genesis_quip_testnet/
密钥生成scripts/derive-operator-keys.sh、crates/transaction-crypto/examples/derive_genesis_keys.rs
运维文档docs/testnet-keys.md、docs/genesis-quip-testnet.md

对发布者(release coordinator)而言,一次完整的测试网版本发布可以浓缩为:在 rc 分支上完成 pre-tag 全量检查 → 推送v<MAJOR>.<MINOR>.<PATCH>-rcN标签验证 CI 与镜像 → 全绿后合入 main 并推送正式标签 → 完成 post-tag 四步验证 → 通知 operator 按 docs/testnet-keys.md 更新密钥/启动验证节点。若涉及 operator 轮换或新增 slot,还需在创世 preset 中钉入新的公钥材料、重新导出aglais-network.json并同步发布到nodes.quip.network。

【免费下载链接】quip-validator

A rust implementation of the Quip Protocol forked from Substrate

项目地址:https://gitcode.com/gh_mirrors/qu/quip-validator
点击查看免费下载

相关推荐

上一篇:AWS SDK for PHP 在 Laravel 中的使用教程
下一篇:Cookiecutter Django:快速构建生产级Django项目的终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询