mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-07 10:31:19 +00:00
adr-008-priv-validator
This commit is contained in:
parent
459633fb4c
commit
bef91ea7fe
118
docs/architecture/adr-008-priv-validator.md
Normal file
118
docs/architecture/adr-008-priv-validator.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
# ADR 008: PrivValidator
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The current PrivValidator is monolithic and isn't easily reuseable by alternative signers.
|
||||||
|
|
||||||
|
For instance, see https://github.com/tendermint/tendermint/issues/673
|
||||||
|
|
||||||
|
The goal is to have a clean PrivValidator interface like:
|
||||||
|
|
||||||
|
``
|
||||||
|
type PrivValidator interface {
|
||||||
|
Address() data.Bytes
|
||||||
|
PubKey() crypto.PubKey
|
||||||
|
|
||||||
|
SignVote(chainID string, vote *types.Vote) error
|
||||||
|
SignProposal(chainID string, proposal *types.Proposal) error
|
||||||
|
SignHeartbeat(chainID string, heartbeat *types.Heartbeat) error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It should also be easy to re-use the LastSignedInfo logic to avoid double signing.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Tendermint node's should support only two in-process PrivValidator implementations:
|
||||||
|
|
||||||
|
- PrivValidatorUnencrypted uses an unencrypted private key in a "priv_validator.json" file - no configuration required (just `tendermint init`).
|
||||||
|
- PrivValidatorSocket uses a socket to send signing requests to another process - user is responsible for starting that process themselves.
|
||||||
|
|
||||||
|
The PrivValidatorSocket address can be provided via flags at the command line -
|
||||||
|
doing so will cause Tendermint to ignore any "priv_validator.json" file and to attempt
|
||||||
|
to connect over the socket.
|
||||||
|
|
||||||
|
In addition, Tendermint will provide implementations that can be run in that external process.
|
||||||
|
These include:
|
||||||
|
|
||||||
|
- PrivValidatorEncrypted uses an encrypted private key persisted to disk - user must enter password to decrypt key when process is started.
|
||||||
|
- PrivValidatorLedger uses a Ledger Nano S to handle all signing.
|
||||||
|
|
||||||
|
What follows are descriptions of useful types
|
||||||
|
|
||||||
|
### Signer
|
||||||
|
|
||||||
|
```
|
||||||
|
type Signer interface {
|
||||||
|
Sign(msg []byte) (crypto.Signature, error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Signer signs a message. It can also return an error.
|
||||||
|
|
||||||
|
### ValidatorID
|
||||||
|
|
||||||
|
|
||||||
|
ValidatorID is just the Address and PubKey
|
||||||
|
|
||||||
|
```
|
||||||
|
type ValidatorID struct {
|
||||||
|
Address data.Bytes `json:"address"`
|
||||||
|
PubKey crypto.PubKey `json:"pub_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
### LastSignedInfo
|
||||||
|
|
||||||
|
LastSignedInfo tracks the last thing we signed:
|
||||||
|
|
||||||
|
```
|
||||||
|
type LastSignedInfo struct {
|
||||||
|
Height int64 `json:"height"`
|
||||||
|
Round int `json:"round"`
|
||||||
|
Step int8 `json:"step"`
|
||||||
|
Signature crypto.Signature `json:"signature,omitempty"` // so we dont lose signatures
|
||||||
|
SignBytes data.Bytes `json:"signbytes,omitempty"` // so we dont lose signatures
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It exposes methods for signing votes and proposals using a `Signer`.
|
||||||
|
|
||||||
|
This allows it to easily be reused by developers implemented their own PrivValidator.
|
||||||
|
|
||||||
|
### PrivValidatorUnencrypted
|
||||||
|
|
||||||
|
```
|
||||||
|
type PrivValidatorUnencrypted struct {
|
||||||
|
ID types.ValidatorID `json:"id"`
|
||||||
|
PrivKey PrivKey `json:"priv_key"`
|
||||||
|
LastSignedInfo *LastSignedInfo `json:"last_signed_info"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Has the same structure as currently, but broken up into sub structs.
|
||||||
|
|
||||||
|
Note the LastSignedInfo is mutated in place every time we sign.
|
||||||
|
|
||||||
|
### PrivValidatorJSON
|
||||||
|
|
||||||
|
The "priv_validator.json" file supports only the PrivValidatorUnencrypted type.
|
||||||
|
|
||||||
|
It unmarshals into PrivValidatorJSON, which is used as the default PrivValidator type.
|
||||||
|
It wraps the PrivValidatorUnencrypted and persists it to disk after every signature.
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Proposed.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
|
||||||
|
- Cleaner separation of components enabling re-use.
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
|
||||||
|
- More files - led to creation of new directory.
|
||||||
|
|
||||||
|
### Neutral
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user