You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
8.3 KiB

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