github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/docs/architecture/adr-009-ABCI-design.md (about) 1 # ADR 009: ABCI UX Improvements 2 3 ## Changelog 4 5 23-06-2018: Some minor fixes from review 6 07-06-2018: Some updates based on discussion with Jae 7 07-06-2018: Initial draft to match what was released in ABCI v0.11 8 9 ## Context 10 11 The ABCI was first introduced in late 2015. It's purpose is to be: 12 13 - a generic interface between state machines and their replication engines 14 - agnostic to the language the state machine is written in 15 - agnostic to the replication engine that drives it 16 17 This means ABCI should provide an interface for both pluggable applications and 18 pluggable consensus engines. 19 20 To achieve this, it uses Protocol Buffers (proto3) for message types. The dominant 21 implementation is in Go. 22 23 After some recent discussions with the community on github, the following were 24 identified as pain points: 25 26 - Amino encoded types 27 - Managing validator sets 28 - Imports in the protobuf file 29 30 See the [references](#references) for more. 31 32 ### Imports 33 34 The native proto library in Go generates inflexible and verbose code. 35 Many in the Go community have adopted a fork called 36 [gogoproto](https://github.com/cosmos/gogoproto) that provides a 37 variety of features aimed to improve the developer experience. 38 While `gogoproto` is nice, it creates an additional dependency, and compiling 39 the protobuf types for other languages has been reported to fail when `gogoproto` is used. 40 41 ### Amino 42 43 Amino is an encoding protocol designed to improve over insufficiencies of protobuf. 44 It's goal is to be proto4. 45 46 Many people are frustrated by incompatibility with protobuf, 47 and with the requirement for Amino to be used at all within ABCI. 48 49 We intend to make Amino successful enough that we can eventually use it for ABCI 50 message types directly. By then it should be called proto4. In the meantime, 51 we want it to be easy to use. 52 53 ### PubKey 54 55 PubKeys are encoded using Amino (and before that, go-wire). 56 Ideally, PubKeys are an interface type where we don't know all the 57 implementation types, so its unfitting to use `oneof` or `enum`. 58 59 ### Addresses 60 61 The address for ED25519 pubkey is the RIPEMD160 of the Amino 62 encoded pubkey. This introduces an Amino dependency in the address generation, 63 a functionality that is widely required and should be easy to compute as 64 possible. 65 66 ### Validators 67 68 To change the validator set, applications can return a list of validator updates 69 with ResponseEndBlock. In these updates, the public key _must_ be included, 70 because Tendermint requires the public key to verify validator signatures. This 71 means ABCI developers have to work with PubKeys. That said, it would also be 72 convenient to work with address information, and for it to be simple to do so. 73 74 ### AbsentValidators 75 76 Tendermint also provides a list of validators in BeginBlock who did not sign the 77 last block. This allows applications to reflect availability behavior in the 78 application, for instance by punishing validators for not having votes included 79 in commits. 80 81 ### InitChain 82 83 Tendermint passes in a list of validators here, and nothing else. It would 84 benefit the application to be able to control the initial validator set. For 85 instance the genesis file could include application-based information about the 86 initial validator set that the application could process to determine the 87 initial validator set. Additionally, InitChain would benefit from getting all 88 the genesis information. 89 90 ### Header 91 92 ABCI provides the Header in RequestBeginBlock so the application can have 93 important information about the latest state of the blockchain. 94 95 ## Decision 96 97 ### Imports 98 99 Move away from gogoproto. In the short term, we will just maintain a second 100 protobuf file without the gogoproto annotations. In the medium term, we will 101 make copies of all the structs in Golang and shuttle back and forth. In the long 102 term, we will use Amino. 103 104 ### Amino 105 106 To simplify ABCI application development in the short term, 107 Amino will be completely removed from the ABCI: 108 109 - It will not be required for PubKey encoding 110 - It will not be required for computing PubKey addresses 111 112 That said, we are working to make Amino a huge success, and to become proto4. 113 To facilitate adoption and cross-language compatibility in the near-term, Amino 114 v1 will: 115 116 - be fully compatible with the subset of proto3 that excludes `oneof` 117 - use the Amino prefix system to provide interface types, as opposed to `oneof` 118 style union types. 119 120 That said, an Amino v2 will be worked on to improve the performance of the 121 format and its useability in cryptographic applications. 122 123 ### PubKey 124 125 Encoding schemes infect software. As a generic middleware, ABCI aims to have 126 some cross scheme compatibility. For this it has no choice but to include opaque 127 bytes from time to time. While we will not enforce Amino encoding for these 128 bytes yet, we need to provide a type system. The simplest way to do this is to 129 use a type string. 130 131 PubKey will now look like: 132 133 ``` 134 message PubKey { 135 string type 136 bytes data 137 } 138 ``` 139 140 where `type` can be: 141 142 - "ed225519", with `data = <raw 32-byte pubkey>` 143 - "secp256k1", with `data = <33-byte OpenSSL compressed pubkey>` 144 145 As we want to retain flexibility here, and since ideally, PubKey would be an 146 interface type, we do not use `enum` or `oneof`. 147 148 ### Addresses 149 150 To simplify and improve computing addresses, we change it to the first 20-bytes of the SHA256 151 of the raw 32-byte public key. 152 153 We continue to use the Bitcoin address scheme for secp256k1 keys. 154 155 ### Validators 156 157 Add a `bytes address` field: 158 159 ``` 160 message Validator { 161 bytes address 162 PubKey pub_key 163 int64 power 164 } 165 ``` 166 167 ### RequestBeginBlock and AbsentValidators 168 169 To simplify this, RequestBeginBlock will include the complete validator set, 170 including the address, and voting power of each validator, along 171 with a boolean for whether or not they voted: 172 173 ``` 174 message RequestBeginBlock { 175 bytes hash 176 Header header 177 LastCommitInfo last_commit_info 178 repeated Evidence byzantine_validators 179 } 180 181 message LastCommitInfo { 182 int32 CommitRound 183 repeated SigningValidator validators 184 } 185 186 message SigningValidator { 187 Validator validator 188 bool signed_last_block 189 } 190 ``` 191 192 Note that in Validators in RequestBeginBlock, we DO NOT include public keys. Public keys are 193 larger than addresses and in the future, with quantum computers, will be much 194 larger. The overhead of passing them, especially during fast-sync, is 195 significant. 196 197 Additional, addresses are changing to be simpler to compute, further removing 198 the need to include pubkeys here. 199 200 In short, ABCI developers must be aware of both addresses and public keys. 201 202 ### ResponseEndBlock 203 204 Since ResponseEndBlock includes Validator, it must now include their address. 205 206 ### InitChain 207 208 Change RequestInitChain to give the app all the information from the genesis file: 209 210 ``` 211 message RequestInitChain { 212 int64 time 213 string chain_id 214 ConsensusParams consensus_params 215 repeated Validator validators 216 bytes app_state_bytes 217 } 218 ``` 219 220 Change ResponseInitChain to allow the app to specify the initial validator set 221 and consensus parameters. 222 223 ``` 224 message ResponseInitChain { 225 ConsensusParams consensus_params 226 repeated Validator validators 227 } 228 ``` 229 230 ### Header 231 232 Now that Tendermint Amino will be compatible with proto3, the Header in ABCI 233 should exactly match the Tendermint header - they will then be encoded 234 identically in ABCI and in Tendermint Core. 235 236 ## Status 237 238 Implemented 239 240 ## Consequences 241 242 ### Positive 243 244 - Easier for developers to build on the ABCI 245 - ABCI and Tendermint headers are identically serialized 246 247 ### Negative 248 249 - Maintenance overhead of alternative type encoding scheme 250 - Performance overhead of passing all validator info every block (at least its 251 only addresses, and not also pubkeys) 252 - Maintenance overhead of duplicate types 253 254 ### Neutral 255 256 - ABCI developers must know about validator addresses 257 258 ## References 259 260 - [ABCI v0.10.3 Specification (before this 261 proposal)](https://github.com/tendermint/abci/blob/v0.10.3/specification.rst) 262 - [ABCI v0.11.0 Specification (implementing first draft of this 263 proposal)](https://github.com/tendermint/abci/blob/v0.11.0/specification.md) 264 - [Ed25519 addresses](https://github.com/tendermint/go-crypto/issues/103) 265 - [InitChain contains the 266 Genesis](https://github.com/tendermint/abci/issues/216) 267 - [PubKeys](https://github.com/tendermint/tendermint/issues/1524) 268 - [Notes on 269 Header](https://github.com/tendermint/tendermint/issues/1605) 270 - [Gogoproto issues](https://github.com/tendermint/abci/issues/256) 271 - [Absent Validators](https://github.com/tendermint/abci/issues/231)