github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/docs/architecture/adr-081-protobuf-mgmt.md (about) 1 # ADR 081: Protocol Buffers Management 2 3 ## Changelog 4 5 - 2022-02-28: First draft 6 7 ## Status 8 9 Accepted 10 11 [Tracking issue](https://github.com/tendermint/tendermint/issues/8121) 12 13 ## Context 14 15 At present, we manage the [Protocol Buffers] schema files ("protos") that define 16 our wire-level data formats within the Tendermint repository itself (see the 17 [`proto`](../../proto/) directory). Recently, we have been making use of [Buf], 18 both locally and in CI, in order to generate Go stubs, and lint and check 19 `.proto` files for breaking changes. 20 21 The version of Buf used at the time of this decision was `v1beta1`, and it was 22 discussed in [\#7975] and in weekly calls as to whether we should upgrade to 23 `v1` and harmonize our approach with that used by the Cosmos SDK. The team 24 managing the Cosmos SDK was primarily interested in having our protos versioned 25 and easily accessible from the [Buf] registry. 26 27 The three main sets of stakeholders for the `.proto` files and their needs, as 28 currently understood, are as follows. 29 30 1. Tendermint needs Go code generated from `.proto` files. 31 2. Consumers of Tendermint's `.proto` files, specifically projects that want to 32 interoperate with Tendermint and need to generate code for their own 33 programming language, want to be able to access these files in a reliable and 34 efficient way. 35 3. The Tendermint Core team wants to provide stable interfaces that are as easy 36 as possible to maintain, on which consumers can depend, and to be able to 37 notify those consumers promptly when those interfaces change. To this end, we 38 want to: 39 1. Prevent any breaking changes from being introduced in minor/patch releases 40 of Tendermint. Only major version updates should be able to contain 41 breaking interface changes. 42 2. Prevent generated code from diverging from the Protobuf schema files. 43 44 There was also discussion surrounding the notion of automated documentation 45 generation and hosting, but it is not clear at this time whether this would be 46 that valuable to any of our stakeholders. What will, of course, be valuable at 47 minimum would be better documentation (in comments) of the `.proto` files 48 themselves. 49 50 ## Alternative Approaches 51 52 ### Meeting stakeholders' needs 53 54 1. Go stub generation from protos. We could use: 55 1. [Buf]. This approach has been rather cumbersome up to this point, and it 56 is not clear what Buf really provides beyond that which `protoc` provides 57 to justify the additional complexity in configuring Buf for stub 58 generation. 59 2. [protoc] - the Protocol Buffers compiler. 60 2. Notification of breaking changes: 61 1. Buf in CI for all pull requests to *release* branches only (and not on 62 `master`). 63 2. Buf in CI on every pull request to every branch (this was the case at the 64 time of this decision, and the team decided that the signal-to-noise ratio 65 for this approach was too low to be of value). 66 3. `.proto` linting: 67 1. Buf in CI on every pull request 68 4. `.proto` formatting: 69 1. [clang-format] locally and a [clang-format GitHub Action] in CI to check 70 that files are formatted properly on every pull request. 71 5. Sharing of `.proto` files in a versioned, reliable manner: 72 1. Consumers could simply clone the Tendermint repository, check out a 73 specific commit, tag or branch and manually copy out all of the `.proto` 74 files they need. This requires no effort from the Tendermint Core team and 75 will continue to be an option for consumers. The drawback of this approach 76 is that it requires manual coding/scripting to implement and is brittle in 77 the face of bigger changes. 78 2. Uploading our `.proto` files to Buf's registry on every release. This is 79 by far the most seamless for consumers of our `.proto` files, but requires 80 the dependency on Buf. This has the additional benefit that the Buf 81 registry will automatically [generate and host 82 documentation][buf-docs-gen] for these protos. 83 3. We could create a process that, upon release, creates a `.zip` file 84 containing our `.proto` files. 85 86 ### Popular alternatives to Buf 87 88 [Prototool] was not considered as it appears deprecated, and the ecosystem seems 89 to be converging on Buf at this time. 90 91 ### Tooling complexity 92 93 The more tools we have in our build/CI processes, the more complex and fragile 94 repository/CI management becomes, and the longer it takes to onboard new team 95 members. Maintainability is a core concern here. 96 97 ### Buf sustainability and costs 98 99 One of the primary considerations regarding the usage of Buf is whether, for 100 example, access to its registry will eventually become a 101 paid-for/subscription-based service and whether this is valuable enough for us 102 and the ecosystem to pay for such a service. At this time, it appears as though 103 Buf will never charge for hosting open source projects' protos. 104 105 Another consideration was Buf's sustainability as a project - what happens when 106 their resources run out? Will there be a strong and broad enough open source 107 community to continue maintaining it? 108 109 ### Local Buf usage options 110 111 Local usage of Buf (i.e. not in CI) can be accomplished in two ways: 112 113 1. Installing the relevant tools individually. 114 2. By way of its [Docker image][buf-docker]. 115 116 Local installation of Buf requires developers to manually keep their toolchains 117 up-to-date. The Docker option comes with a number of complexities, including 118 how the file system permissions of code generated by a Docker container differ 119 between platforms (e.g. on Linux, Buf-generated code ends up being owned by 120 `root`). 121 122 The trouble with the Docker-based approach is that we make use of the 123 [gogoprotobuf] plugin for `protoc`. Continuing to use the Docker-based approach 124 to using Buf will mean that we will have to continue building our own custom 125 Docker image with embedded gogoprotobuf. 126 127 Along these lines, we could eventually consider coming up with a [Nix]- or 128 [redo]-based approach to developer tooling to ensure tooling consistency across 129 the team and for anyone who wants to be able to contribute to Tendermint. 130 131 ## Decision 132 133 1. We will adopt Buf for now for proto generation, linting, breakage checking 134 and its registry (mainly in CI, with optional usage locally). 135 2. Failing CI when checking for breaking changes in `.proto` files will only 136 happen when performing minor/patch releases. 137 3. Local tooling will be favored over Docker-based tooling. 138 139 ## Detailed Design 140 141 We currently aim to: 142 143 1. Update to Buf `v1` to facilitate linting, breakage checking and uploading to 144 the Buf registry. 145 2. Configure CI appropriately for proto management: 146 1. Uploading protos to the Buf registry on every release (e.g. the 147 [approach][cosmos-sdk-buf-registry-ci] used by the Cosmos SDK). 148 2. Linting on every pull request (e.g. the 149 [approach][cosmos-sdk-buf-linting-ci] used by the Cosmos SDK). The linter 150 passing should be considered a requirement for accepting PRs. 151 3. Checking for breaking changes in minor/patch version releases and failing 152 CI accordingly - see [\#8003]. 153 4. Add [clang-format GitHub Action] to check `.proto` file formatting. Format 154 checking should be considered a requirement for accepting PRs. 155 3. Update the Tendermint [`Makefile`](../../Makefile) to primarily facilitate 156 local Protobuf stub generation, linting, formatting and breaking change 157 checking. More specifically: 158 1. This includes removing the dependency on Docker and introducing the 159 dependency on local toolchain installation. CI-based equivalents, where 160 relevant, will rely on specific GitHub Actions instead of the Makefile. 161 2. Go code generation will rely on `protoc` directly. 162 163 ## Consequences 164 165 ### Positive 166 167 - We will still offer Go stub generation, proto linting and breakage checking. 168 - Breakage checking will only happen on minor/patch releases to increase the 169 signal-to-noise ratio in CI. 170 - Versioned protos will be made available via Buf's registry upon every release. 171 172 ### Negative 173 174 - Developers/contributors will need to install the relevant Protocol 175 Buffers-related tooling (Buf, gogoprotobuf, clang-format) locally in order to 176 build, lint, format and check `.proto` files for breaking changes. 177 178 ### Neutral 179 180 ## References 181 182 - [Protocol Buffers] 183 - [Buf] 184 - [\#7975] 185 - [protoc] - The Protocol Buffers compiler 186 187 [Protocol Buffers]: https://developers.google.com/protocol-buffers 188 [Buf]: https://buf.build/ 189 [\#7975]: https://github.com/tendermint/tendermint/pull/7975 190 [protoc]: https://github.com/protocolbuffers/protobuf 191 [clang-format]: https://clang.llvm.org/docs/ClangFormat.html 192 [clang-format GitHub Action]: https://github.com/marketplace/actions/clang-format-github-action 193 [buf-docker]: https://hub.docker.com/r/bufbuild/buf 194 [cosmos-sdk-buf-registry-ci]: https://github.com/cosmos/cosmos-sdk/blob/e6571906043b6751951a42b6546431b1c38b05bd/.github/workflows/proto-registry.yml 195 [cosmos-sdk-buf-linting-ci]: https://github.com/cosmos/cosmos-sdk/blob/e6571906043b6751951a42b6546431b1c38b05bd/.github/workflows/proto.yml#L15 196 [\#8003]: https://github.com/tendermint/tendermint/issues/8003 197 [Nix]: https://nixos.org/ 198 [gogoprotobuf]: https://github.com/cosmos/gogoproto 199 [Prototool]: https://github.com/uber/prototool 200 [buf-docs-gen]: https://docs.buf.build/bsr/documentation 201 [redo]: https://redo.readthedocs.io/en/latest/