区块链共识算法【免费下载链接】tendermint⟁ Tendermint Core (BFT Consensus) in Go项目地址https://gitcode.com/gh_mirrors/te/tendermint点击查看免费下载导读本指南以 Tendermint 仓库中 proto/README.md 为主体系统讲解proto/目录在整个项目中的定位它定义了跨实现Tendermint-Go 与 Tendermint-rs 等共享的核心类型与消息是共识协议、ABCI 接口、P2P 网络与状态同步等一切线上数据格式的单一事实来源。读完本文你将掌握 proto 包的目录结构、与 spec 核心数据结构 及 ABCI 规范 的分工关系、官方要求的更新与版本发布流程以及仓库中实际的 buf 代码生成工具链能够正确地在 Tendermint 生态中发起、评审与落地一次协议变更。proto 目录的定位跨实现的共享类型与消息Tendermint 是一个用 Go 编写的 BFT 共识引擎状态机复制引擎而链上的区块、投票、提案、证据等数据结构必须被所有参与节点以完全一致的字节格式解析。为此仓库在根目录下维护了一个独立的proto/目录proto/README.md 明确指出This sections defines the types and messages shared across implementations.也就是说proto/不是某个包内部的私有实现细节而是整个协议对外承诺的公共契约。其中核心数据类型区块、区块头、投票、提案、证据等的结构化语义定义在 spec/core/data_structures.mdABCIApplication Blockchain Interface的接口与消息定义在 spec/abci/README.md 一节更细的方法与类型见 spec/abci/abci.md 和 spec/abci/apps.md。proto/中的.proto文件与上述规范文档一一对应规范负责用自然语言与表格描述是什么、为什么、如何校验.proto文件则用机器可读的方式固定在线上长什么样。例如 proto/tendermint/types/block.proto 中的Block消息就精确对应 spec/core/data_structures.md 中描述的 Block 结构header、data、evidence、last_commit 四个字段。目录结构14 个协议包一览从仓库根目录看proto/下只有一个顶层命名空间目录tendermint/其内部按功能域拆分为 14 个包每个包内通常是一个或多个.proto源文件与对应的生成代码*.pb.go包路径职责关键 proto 文件proto/tendermint/abciABCI 请求/响应消息与服务定义types.protoproto/tendermint/blockchain区块链同步快速同步的请求/响应types.protoproto/tendermint/consensus共识 Reactor 消息与 WAL 日志消息types.proto、wal.protoproto/tendermint/crypto公钥与默克尔证明keys.proto、proof.protoproto/tendermint/libs/bitsBitArray 位图序列化types.protoproto/tendermint/mempool交易池 gossip 消息types.protoproto/tendermint/p2pP2P 连接与 PEX 节点交换消息conn.proto、pex.proto、types.protoproto/tendermint/privval远程签名者Private Validator协议types.protoproto/tendermint/rpc/grpc可选的 gRPC 广播接口types.protoproto/tendermint/state状态相关的内部结构types.protoproto/tendermint/statesync状态同步快照消息types.protoproto/tendermint/store区块存储状态types.protoproto/tendermint/types核心区块/投票/证据/参数类型types.proto、block.proto、evidence.proto、params.proto、validator.proto、canonical.proto、events.protoproto/tendermint/version共识与应用的版本号类型types.proto每个.proto文件都通过option go_package声明其 Go 生成代码的导入路径例如github.com/tendermint/tendermint/proto/tendermint/types并配套一份*.pb.go生成文件。需要说明的是proto/tendermint/abci/types.proto 的生成结果在代码生成阶段会被单独移动到abci/types/目录见下文工具链部分因此你在proto/tendermint/abci/下看不到types.pb.go这是有意为之。核心类型的 proto 定义以 Block 与 Header 为例proto/tendermint/types/types.proto是整个协议最重要的文件之一它定义了共识层与存储层共用的核心消息包括BlockIDFlag、SignedMsgType、PartSetHeader、Part、BlockID、Header、Data、Vote、Commit、CommitSig、Proposal、SignedHeader、LightBlock、BlockMeta、TxProof等。以区块头Header为例其字段布局完整对应 spec/core/data_structures.md 中 Header 的校验表message Header { tendermint.version.Consensus version 1; string chain_id 2; int64 height 3; google.protobuf.Timestamp time 4; BlockID last_block_id 5; bytes last_commit_hash 6; // commit from validators from the last block bytes data_hash 7; // transactions bytes validators_hash 8; // validators for the current block bytes next_validators_hash 9; // validators for the next block bytes consensus_hash 10; // consensus params for current block bytes app_hash 11; // state after txs from the previous block bytes last_results_hash 12; // root hash of all results from the txs from the previous block bytes evidence_hash 13; // evidence included in the block bytes proposer_address 14; // original proposer of the block }值得注意的几个设计细节时间类型time字段使用google.protobuf.Timestamp配合(gogoproto.stdtime) true扩展在 Go 中直接映射为标准库time.Time嵌套结构last_block_id使用(gogoproto.nullable) false表示该字段不可为空、直接内嵌从而避免生成指针字段自定义名称chain_id通过(gogoproto.customname) ChainID让 Go 生成字段名符合项目惯例。与之配套Block的组装在 block.proto 中完成Header、Data、EvidenceList 三者为必填内嵌last_commit允许为空初始高度时没有上一轮的 Commit。而 evidence.proto 用oneof sum聚合了两类链上证据DuplicateVoteEvidence双签与LightClientAttackEvidence轻客户端攻击对应 evidence/pool.go 中证据池处理的对象。version包中的 types.proto 定义了App应用协议号与软件版本和Consensus区块协议版本与应用版本后者会被哈希进Header.ConsensusHash用于保证网络中所有节点运行同一套共识规则。ABCI应用与共识引擎之间的协议契约ABCIApplication Blockchain Interface是 Tendermint 与应用状态机之间的接口全部消息与方法都定义在 proto/tendermint/abci/types.proto 中该文件顶部注释注明copied from http://github.com/tendermint/abci。规范层面由 spec/abci/README.md 统领其导言说明Tendermint 通过发送Request*消息、接收Response*消息来调用 ABCI 应用从而完成状态机复制由于全部消息用 Protocol Buffers 定义Tendermint 可以驱动任意语言编写的应用。该文件的核心构成Request/Response各用oneof value聚合了 15/16 种消息覆盖Echo、Flush、Info、InitChain、CheckTx、DeliverTx、Query、Commit、BeginBlock、EndBlock以及状态同步专用的ListSnapshots、OfferSnapshot、LoadSnapshotChunk、ApplySnapshotChunkservice ABCIApplication定义了 15 个 RPC 方法声明了pluginsgrpc时生成的 gRPC 服务同时abci/client 与 abci/server 提供 socket 与 gRPC 两种传输实现辅助类型ConsensusParams含BlockParams.max_bytes/max_gas、EvidenceParams、ValidatorParams、VersionParams、Event/EventAttribute用于交易索引、TxResult、Validator/ValidatorUpdate、VoteInfo、Evidence、Snapshot等。从实现侧看types/protobuf.go 提供了TM2PB转换器tm2pb结构体把 Go 内部类型如Header、Validator转换为 protobuf 消息其注释明确标注UNSTABLE提醒这些转换是为 ABCI 协议服务的边界代码。ABCI 应用的参考实现kvstore、counter位于 abci/example。更新流程协议变更的官方步骤proto/README.md 明确警告proto/下的.proto文件是协议的核心core to the protocol任何更新都必须按流程严肃对待。官方规定的步骤如下提交 issue 描述变更提案。issue 中需要由 Tendermint-Go 与 Tendermint-rs 两个团队的成员共同评论。如果无法达成共识可以进一步要求发起 RFC注当前仓库中rfc/目录位于 spec 工作区本仓库未包含应以 spec 仓库为准。1a. 若发起 RFC应以 Pull Request 形式提交以便充分讨论1b. 讨论并合并 RFC。落实变更同步修改对应的.proto文件、核心数据结构规范 和/或 ABCI 协议规范保证代码即规范、规范即代码两者一致。在 Tendermint-Go 与 Tendermint-rs 仓库各开一个 issue 通知团队用于告知规范发生了变化。3.1 为 issue 打上spec 版本标签。该标签的作用是通知团队变更已经合入 master 分支但尚未进入某个正式 release避免实现侧在发版时遗漏或误打包未就绪的协议变更。这套流程的实质是协议变更必须先经双实现团队评审达成共识再落到.proto与规范文档最后以带版本标签的 issue 同步给各实现仓库从而把跨语言实现一致性纳入正式治理。版本管理策略Tendermint 的 spec 仓库specification目标是版本化发布其策略要点如下协议变更protobuf 更新日常合入 master 分支由 Tendermint-Go 与 Tendermint-rs 团队负责人协商决定每隔一段时间基于 spec 仓库打一个 releasespec 可以包含minor release某些 minor 变更对具体实现可能构成破坏性变更breaking change此时实现团队应当在 spec 仓库中开 issue要求进行一次major release的 spec 版本若各实现都遵循上述打标签 issue的流程那么每个实现的待办清单上都会有对应 spec 变更标签的 issue只有当所有 issue 都完成时团队才宣告 ready for release具备发版条件。从当前仓库的 buf 配置也能印证这种变更即破坏性风险的治理思路根目录 buf.yaml实际生效配置由 buf.work.yaml 指向proto目录中breaking.use: [FILE]表示 buf 会按文件粒度检测破坏性变更Makefile 提供了proto-check-breaking对比本地 git 历史与proto-check-breaking-ci对比远端 v0.34.x 分支两个目标正是该治理流程的落地工具。工具链buf gogofaster 的代码生成proto/目录不只是静态定义还配套了完整的代码生成工具链全部由 buf 生态驱动buf 配置仓库根目录buf.yamlversion: v1deps引入buf.build/gogo/protobuf用于 gogo 扩展breaking按FILE粒度检测lint启用BASIC、FILE_LOWER_SNAKE_CASE、UNARY_RPC三组规则buf.gen.yaml使用gogofaster插件生成到./proto/并配置了关键的M选项将google/protobuf/timestamp.proto映射到github.com/gogo/protobuf/types、duration.proto映射到github.com/golang/protobuf/ptypes/duration、pluginsgrpc生成 gRPC 服务代码、pathssource_relative按源文件相对路径输出buf.lock锁定 gogo/protobuf 依赖的远端 commit4df00b267f944190a229ce3695781e99保证可复现构建buf.work.yaml将proto目录纳入 buf workspace。Makefile 目标Makefile 中### Protobuf ###一节proto-gen: check-proto-deps echo Generating Protobuf files go run github.com/bufbuild/buf/cmd/buf generate mv ./proto/tendermint/abci/types.pb.go ./abci/types/proto-gen先生成所有*.pb.go再把 ABCI 的生成结果移到abci/types/供应用侧使用proto-lint运行buf lint校验命名与风格如小写下划线文件名proto-format用clang-format统一格式化proto/*.protoproto-check-breaking/proto-check-breaking-ci分别对比本地 git 历史与远端分支做破坏性变更检测。一键脚本scripts/proto-gen.sh 封装了完整流程——在仓库根目录启动golang:1.18-alpineDocker 容器安装buf与protoc-gen-gogofaster后执行make proto-gen。脚本注释明确说明其目的是在容器内安装正确版本的工具避免污染本地环境。对于本仓库的贡献者重新生成代码推荐直接使用该脚本或对应 Makefile 目标而不是手动调用 protoc。网络与共识消息P2P 包中的 oneof 消息模式Tendermint 的 P2P 层协议也完全以 protobuf 定义且普遍采用外层Message聚合 oneof的约定。例如blockchain/types.protoMessage聚合BlockRequest、NoBlockResponse、BlockResponse、StatusRequest、StatusResponse对应快速同步时节点间按高度拉取区块的交互p2p/pex.protoPexRequest/PexAddrs对应 PEX 节点交换协议见 p2p/pex/pex_reactor.go 的实现mempool/types.protoTxs批量携带交易字节对应交易池 gossipstatesync/types.protoSnapshotsRequest/Response与ChunkRequest/Response对应状态同步中快照发现与分块拉取见 statesync/reactor.goconsensus/wal.protoWALMessage聚合EventDataRoundState、MsgInfo、TimeoutInfo、EndHeightTimedWALMessage再包裹时间戳——这正是共识写前日志WAL的持久化格式consensus/wal.go 与 scripts/wal2json、scripts/json2wal 都基于它工作。这种一个包一个Message oneof的约定让每个 reactor 只需处理一种入口消息类型显著简化了 P2P 消息分发逻辑。签名与规范字节Canonical 类型的作用签名是 BFT 共识正确性的基石而签名字节必须与网络传输字节解耦。为此 proto/tendermint/types/canonical.proto 定义了CanonicalVote、CanonicalProposal、CanonicalBlockID、CanonicalPartSetHeader投票在网络上用Vote传播但在签名时通过VoteSignBytes(chainID, vote)转换成CanonicalVote再编码——多出的chain_id字段和固定的sfixed64编码sfixed64注释写明canonicalization requires fixed size encoding here保证了签名语义在所有实现间绝对一致这与 spec/core/data_structures.md 中CanonicalVote一节的描述完全吻合规范明确指出CanonicalVotewill not be present in a block仅用于 validator 签名。因此任何修改types.proto中Vote字段的提案都必须同步评估canonical.proto中的签名表示——这正是 README 要求同步修改 .proto 与规范文档的现实原因。其他配套 protoprivval 与 rpc/grpcprivval/types.proto 定义了远程签名者协议PubKeyRequest/Response、SignVoteRequest/Response、SignProposalRequest/Response、PingRequest/Response以及统一的Errors枚举和RemoteSignerError。它支撑 privval 包中 socket 签名服务signer_server.go、signer_client.go的实现rpc/grpc/types.proto 定义可选的BroadcastAPIgRPC 服务Ping与BroadcastTx生成代码包名为coregrpc对应 rpc/grpc 目录中的实现。实践建议如何在当前仓库中查看与验证协议对于希望深入理解或贡献协议定义的读者推荐按以下路径阅读与验证仓库为只读仅支持查看与本地验证不要修改仓库内容从规范入手先读 spec/core/data_structures.md区块、Header、Vote、Proposal 等的字段与校验规则与 spec/abci/README.md建立语义模型对照 proto 定义打开 types.proto 与 abci/types.proto确认字段编号、类型与规范表格一一对应追踪生成代码在proto/tendermint/types/types.pb.go等生成文件中查看 Go 结构体与方法如Header.XXX_、Marshal/Unmarshal理解字段如何被序列化验证转换边界阅读 types/protobuf.go 的TM2PB转换与 types/signable.go 中的VoteSignBytes理解内部类型与线上字节之间的映射本地复现生成如环境具备 Docker 与 Go 工具链可运行make proto-gen或 scripts/proto-gen.sh在本地临时目录验证生成结果并通过make proto-lint、make proto-check-breaking检查风格与破坏性变更。总结Tendermint 的proto/目录是协议层的中枢它用 Protocol Buffers 精确锁定跨实现共享的类型与消息与spec/下的规范文档互为表里任何变更都必须遵循双团队评审 → RFC可选→ 同步修改 .proto 与规范 → 带 spec 版本标签的 issue 通知的治理流程并由 spec 仓库的 minor/major release 机制控制版本演进。对开发者而言理解 proto/README.md、掌握 buf 工具链与oneof消息约定是参与 Tendermint 生态开发、实现自定义 ABCI 应用或构建兼容客户端的第一步。赞分享区块链共识算法【免费下载链接】tendermint⟁ Tendermint Core (BFT Consensus) in Go项目地址https://gitcode.com/gh_mirrors/te/tendermint点击查看免费下载相关推荐Terraform 插件协议新版本发布全流程从 .proto 定义到 Registry 兼容校验的实践指南Terraform 插件协议新版本发布全流程从 .proto 定义到 Registry 兼容校验的实践指南 Terraform 的插件协议Plugin PrIaCCLI基础设施云原生DevOpsDelta 协议演进治理指南解读 protocol_rfcs 目录与 RFC 全流程Delta 协议演进治理指南解读 protocol_rfcs 目录与 RFC 全流程 Delta Lake 的事务日志协议Transaction Log P湖仓一体数据工程数据湖Protobuf-TS v2.10.0 版本发布更稳定的协议缓冲区工具链Protobuf TS v2.10.0 版本发布更稳定的协议缓冲区工具链 Protobuf TS 是一个基于 TypeScript 的 Protocol Bu上一篇iOS激活锁绕过终极指南applera1n让你的iPhone 6s-X设备重获自由下一篇解锁微信聊天记录的永久保存与智能分析WeChatMsg深度探索创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考