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)