mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-08 13:02:14 +00:00
206 lines
5.8 KiB
Markdown
206 lines
5.8 KiB
Markdown
|
# ADR 009: ABCI UX Improvements
|
||
|
|
||
|
## Context
|
||
|
|
||
|
The ABCI was first introduced in late 2015. It's purpose is to be:
|
||
|
|
||
|
- a generic interface between state machines and their replication engines
|
||
|
- agnostic to the language the state machine is written in
|
||
|
- agnostic to the replication engine that drives it
|
||
|
|
||
|
This means ABCI should provide an interface for both pluggable applications and
|
||
|
pluggable consensus engines.
|
||
|
|
||
|
To achieve this, it uses Protocol Buffers for message types. The dominant
|
||
|
implementation is in Go.
|
||
|
|
||
|
After some recent discussions with the community on github, the following were
|
||
|
identified as pain points:
|
||
|
|
||
|
- Amino encoded types
|
||
|
- Managing validator sets
|
||
|
- Imports in the protobuf file
|
||
|
|
||
|
See the following relevent github issues:
|
||
|
- TODO
|
||
|
|
||
|
### Imports
|
||
|
|
||
|
The native Protobuf library in Go generates code that is inellegant and difficult to work with.
|
||
|
The solution in the Go community is to use a fork of it called `gogoproto`.
|
||
|
While `gogoproto` is nice, it creates an additional dependency, and compiling
|
||
|
the protobuf types for other languages has been reported to fail when `gogoproto` is used.
|
||
|
|
||
|
### Amino
|
||
|
|
||
|
Amino is an encoding protocol designed to improve over insufficiencies of protobuf.
|
||
|
It's goal is to be Protobuf4.
|
||
|
|
||
|
Many people are frustrated by incompatibility with protobuf,
|
||
|
and with the requirement for Amino to be used at all within ABCI.
|
||
|
|
||
|
We intend to make Amino successful enough that we can eventually use it for ABCI
|
||
|
message types directly. By then it should be called Protobuf4. In the meantime,
|
||
|
we want it to be easy to use.
|
||
|
|
||
|
### PubKey
|
||
|
|
||
|
PubKeys were previously encoded using Amino (and before that, go-wire).
|
||
|
|
||
|
### Addresses
|
||
|
|
||
|
The address for an ED25519 pubkey is currently the RIPEMD160 of the Amino
|
||
|
encoded pubkey.
|
||
|
|
||
|
### Validators
|
||
|
|
||
|
To change the validator set, applications can return a list of validator updates
|
||
|
with ResponseEndBlock. In these updates, the public key *must* be included,
|
||
|
because Tendermint requires the public key to verify validator signatures. This
|
||
|
means ABCI developers have to work with PubKeys. That said, it would also be
|
||
|
convenient to work with address information, and for it to be simple to do so.
|
||
|
|
||
|
### AbsentValidators
|
||
|
|
||
|
Tendermint also provides a list of validators in BeginBlock who did not sign the
|
||
|
last block. This allows applications to reflect availability behaviour in the
|
||
|
application, for instance by punishing validators for not having votes included
|
||
|
in commits.
|
||
|
|
||
|
### InitChain
|
||
|
|
||
|
Tendermint passes in a list of validators here, and nothing else. It would
|
||
|
benefit the application to be able to control the initial validator set. For
|
||
|
instance the genesis file could include application-based information about the
|
||
|
initial validator set that the application could process to determine the
|
||
|
initial validator set. Additionally, InitChain would benefit from getting all
|
||
|
the genesis information.
|
||
|
|
||
|
|
||
|
## Decision
|
||
|
|
||
|
### Imports
|
||
|
|
||
|
Move away from gogoproto. In the short term, we will just maintain a second
|
||
|
protobuf file without the gogoproto annotations. In the medium term, we will
|
||
|
make copies of all the structs in Golang and shuttle back and forth. In the long
|
||
|
term, we will use Amino.
|
||
|
|
||
|
### Amino
|
||
|
|
||
|
To simplify ABCI application development in the short term,
|
||
|
Amino will be completely removed from the ABCI:
|
||
|
|
||
|
- It will not be required for PubKey encoding
|
||
|
- It will not be required for computing PubKey addresses
|
||
|
|
||
|
That said, we are working to make Amino a huge success, and to become Protobuf4.
|
||
|
To facilitate adoption and cross-language compatibility in the near-term, Amino
|
||
|
v1 will:
|
||
|
|
||
|
- be fully compatible with the subset of Protobuf3 that excludes `oneof`
|
||
|
- use the Amino prefix system to provide interface types, as opposed to `oneof`
|
||
|
style union types.
|
||
|
|
||
|
That said, an Amino v2 will be worked on to improve the performance of the
|
||
|
format and its useability in cryptographic applications.
|
||
|
|
||
|
|
||
|
### PubKey
|
||
|
|
||
|
Encoding schemes infect software. As a generic middleware, ABCI aims to have
|
||
|
some cross scheme compatibility. For this it has no choice but to include opaque
|
||
|
bytes from time to time. While we will not enforce Amino encoding for these
|
||
|
bytes yet, we need to provide a type system. The simplest way to do this is to
|
||
|
use a type string.
|
||
|
|
||
|
PubKey will now look like:
|
||
|
|
||
|
```
|
||
|
message PubKey {
|
||
|
string type
|
||
|
bytes data
|
||
|
}
|
||
|
```
|
||
|
|
||
|
where `type` can be:
|
||
|
|
||
|
- "ed225519", with `data = <raw 32-byte pubkey>`
|
||
|
- "secp256k1", with `data = <33-byte OpenSSL compressed pubkey>`
|
||
|
|
||
|
and generated types. At the least we should use a reflection-based protobuf so
|
||
|
we can just encode our own types, rather than using protobuf generated ones.
|
||
|
|
||
|
### Addresses
|
||
|
|
||
|
To simplify and improve computing addresses, we change it to the first 20-bytes of the SHA256
|
||
|
of the raw 32-byte public key.
|
||
|
|
||
|
We continue to use the Bitcoin address scheme for secp256k1 keys.
|
||
|
|
||
|
### Validators
|
||
|
|
||
|
Change the following:
|
||
|
|
||
|
- Validator includes an optional `bytes address` field
|
||
|
- If the field is provided, it *MUST* correspond to the `pubkey.Address()`
|
||
|
|
||
|
|
||
|
```
|
||
|
message Validator {
|
||
|
bytes address
|
||
|
PubKey pub_key
|
||
|
int64 power
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### AbsentValidators
|
||
|
|
||
|
To simplify this, RequestBeginBlock will include the complete validator set,
|
||
|
including the address, public key, and voting power of each validator, along
|
||
|
with a boolean for whether or not they voted:
|
||
|
|
||
|
```
|
||
|
message SigningValidator {
|
||
|
Validator validator
|
||
|
bool signed_last_block
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### InitChain
|
||
|
|
||
|
Change RequestInitChain and ResponseInitChain to
|
||
|
|
||
|
```
|
||
|
message RequestInitChain {
|
||
|
int64 time
|
||
|
string chain_id
|
||
|
ConsensusParams consensus_params
|
||
|
repeated Validator validators
|
||
|
bytes app_state_bytes
|
||
|
}
|
||
|
|
||
|
message ResponseInitChain {
|
||
|
ConsensusParams consensus_params
|
||
|
repeated Validator validators
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Status
|
||
|
|
||
|
Accepted.
|
||
|
|
||
|
## Consequences
|
||
|
|
||
|
### Positive
|
||
|
|
||
|
- Easier for developers to build on the ABCI
|
||
|
|
||
|
### Negative
|
||
|
|
||
|
- Maintenance overhead of alternative type encoding scheme
|
||
|
- Performance overhead of passing all the validator info every block
|
||
|
- Maintenance overhead of duplicate types
|
||
|
|
||
|
### Neutral
|