mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-08 04:52:15 +00:00
* lint docs with write-good, stop-words * remove package-lock.json * update changelog * fix wrong paragraph formatting * fix some docs formatting * fix docs format * fix abci spec format
272 lines
8.3 KiB
Markdown
272 lines
8.3 KiB
Markdown
# ADR 009: ABCI UX Improvements
|
|
|
|
## Changelog
|
|
|
|
23-06-2018: Some minor fixes from review
|
|
07-06-2018: Some updates based on discussion with Jae
|
|
07-06-2018: Initial draft to match what was released in ABCI v0.11
|
|
|
|
## 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 (proto3) 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 [references](#references) for more.
|
|
|
|
### Imports
|
|
|
|
The native proto library in Go generates inflexible and verbose code.
|
|
Many in the Go community have adopted a fork called
|
|
[gogoproto](https://github.com/gogo/protobuf) that provides a
|
|
variety of features aimed to improve the developer experience.
|
|
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 proto4.
|
|
|
|
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 proto4. In the meantime,
|
|
we want it to be easy to use.
|
|
|
|
### PubKey
|
|
|
|
PubKeys are encoded using Amino (and before that, go-wire).
|
|
Ideally, PubKeys are an interface type where we don't know all the
|
|
implementation types, so its unfitting to use `oneof` or `enum`.
|
|
|
|
### Addresses
|
|
|
|
The address for ED25519 pubkey is the RIPEMD160 of the Amino
|
|
encoded pubkey. This introduces an Amino dependency in the address generation,
|
|
a functionality that is widely required and should be easy to compute as
|
|
possible.
|
|
|
|
### 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.
|
|
|
|
### Header
|
|
|
|
ABCI provides the Header in RequestBeginBlock so the application can have
|
|
important information about the latest state of the blockchain.
|
|
|
|
## 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 proto4.
|
|
To facilitate adoption and cross-language compatibility in the near-term, Amino
|
|
v1 will:
|
|
|
|
- be fully compatible with the subset of proto3 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>`
|
|
|
|
As we want to retain flexibility here, and since ideally, PubKey would be an
|
|
interface type, we do not use `enum` or `oneof`.
|
|
|
|
### 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
|
|
|
|
Add a `bytes address` field:
|
|
|
|
```
|
|
message Validator {
|
|
bytes address
|
|
PubKey pub_key
|
|
int64 power
|
|
}
|
|
```
|
|
|
|
### RequestBeginBlock and AbsentValidators
|
|
|
|
To simplify this, RequestBeginBlock will include the complete validator set,
|
|
including the address, and voting power of each validator, along
|
|
with a boolean for whether or not they voted:
|
|
|
|
```
|
|
message RequestBeginBlock {
|
|
bytes hash
|
|
Header header
|
|
LastCommitInfo last_commit_info
|
|
repeated Evidence byzantine_validators
|
|
}
|
|
|
|
message LastCommitInfo {
|
|
int32 CommitRound
|
|
repeated SigningValidator validators
|
|
}
|
|
|
|
message SigningValidator {
|
|
Validator validator
|
|
bool signed_last_block
|
|
}
|
|
```
|
|
|
|
Note that in Validators in RequestBeginBlock, we DO NOT include public keys. Public keys are
|
|
larger than addresses and in the future, with quantum computers, will be much
|
|
larger. The overhead of passing them, especially during fast-sync, is
|
|
significant.
|
|
|
|
Additional, addresses are changing to be simpler to compute, further removing
|
|
the need to include pubkeys here.
|
|
|
|
In short, ABCI developers must be aware of both addresses and public keys.
|
|
|
|
### ResponseEndBlock
|
|
|
|
Since ResponseEndBlock includes Validator, it must now include their address.
|
|
|
|
### InitChain
|
|
|
|
Change RequestInitChain to give the app all the information from the genesis file:
|
|
|
|
```
|
|
message RequestInitChain {
|
|
int64 time
|
|
string chain_id
|
|
ConsensusParams consensus_params
|
|
repeated Validator validators
|
|
bytes app_state_bytes
|
|
}
|
|
```
|
|
|
|
Change ResponseInitChain to allow the app to specify the initial validator set
|
|
and consensus parameters.
|
|
|
|
```
|
|
message ResponseInitChain {
|
|
ConsensusParams consensus_params
|
|
repeated Validator validators
|
|
}
|
|
```
|
|
|
|
### Header
|
|
|
|
Now that Tendermint Amino will be compatible with proto3, the Header in ABCI
|
|
should exactly match the Tendermint header - they will then be encoded
|
|
identically in ABCI and in Tendermint Core.
|
|
|
|
## Status
|
|
|
|
Accepted.
|
|
|
|
## Consequences
|
|
|
|
### Positive
|
|
|
|
- Easier for developers to build on the ABCI
|
|
- ABCI and Tendermint headers are identically serialized
|
|
|
|
### Negative
|
|
|
|
- Maintenance overhead of alternative type encoding scheme
|
|
- Performance overhead of passing all validator info every block (at least its
|
|
only addresses, and not also pubkeys)
|
|
- Maintenance overhead of duplicate types
|
|
|
|
### Neutral
|
|
|
|
- ABCI developers must know about validator addresses
|
|
|
|
## References
|
|
|
|
- [ABCI v0.10.3 Specification (before this
|
|
proposal)](https://github.com/tendermint/abci/blob/v0.10.3/specification.rst)
|
|
- [ABCI v0.11.0 Specification (implementing first draft of this
|
|
proposal)](https://github.com/tendermint/abci/blob/v0.11.0/specification.md)
|
|
- [Ed25519 addresses](https://github.com/tendermint/go-crypto/issues/103)
|
|
- [InitChain contains the
|
|
Genesis](https://github.com/tendermint/abci/issues/216)
|
|
- [PubKeys](https://github.com/tendermint/tendermint/issues/1524)
|
|
- [Notes on
|
|
Header](https://github.com/tendermint/tendermint/issues/1605)
|
|
- [Gogoproto issues](https://github.com/tendermint/abci/issues/256)
|
|
- [Absent Validators](https://github.com/tendermint/abci/issues/231)
|