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.
Tendermint node's should support only two in-process PrivValidator implementations:
tendermint init
).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:
What follows are descriptions of useful types
type Signer interface {
Sign(msg []byte) (crypto.Signature, error)
}
Signer signs a message. It can also return an error.
ValidatorID is just the Address and PubKey
type ValidatorID struct {
Address data.Bytes `json:"address"`
PubKey crypto.PubKey `json:"pub_key"`
}
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.
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.
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.
Proposed.