mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-25 10:41:41 +00:00
more PrivValidator interface
This commit is contained in:
@ -18,7 +18,7 @@ var GenValidatorCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func genValidator(cmd *cobra.Command, args []string) {
|
func genValidator(cmd *cobra.Command, args []string) {
|
||||||
privValidator := types.GenPrivValidator()
|
privValidator := types.GenPrivValidatorFS("")
|
||||||
privValidatorJSONBytes, _ := json.MarshalIndent(privValidator, "", "\t")
|
privValidatorJSONBytes, _ := json.MarshalIndent(privValidator, "", "\t")
|
||||||
fmt.Printf(`%v
|
fmt.Printf(`%v
|
||||||
`, string(privValidatorJSONBytes))
|
`, string(privValidatorJSONBytes))
|
||||||
|
@ -19,8 +19,7 @@ var InitFilesCmd = &cobra.Command{
|
|||||||
func initFiles(cmd *cobra.Command, args []string) {
|
func initFiles(cmd *cobra.Command, args []string) {
|
||||||
privValFile := config.PrivValidatorFile()
|
privValFile := config.PrivValidatorFile()
|
||||||
if _, err := os.Stat(privValFile); os.IsNotExist(err) {
|
if _, err := os.Stat(privValFile); os.IsNotExist(err) {
|
||||||
privValidator := types.GenPrivValidator()
|
privValidator := types.GenPrivValidatorFS(privValFile)
|
||||||
privValidator.SetFile(privValFile)
|
|
||||||
privValidator.Save()
|
privValidator.Save()
|
||||||
|
|
||||||
genFile := config.GenesisFile()
|
genFile := config.GenesisFile()
|
||||||
|
@ -46,14 +46,12 @@ func resetPrivValidator(cmd *cobra.Command, args []string) {
|
|||||||
|
|
||||||
func resetPrivValidatorLocal(privValFile string, logger log.Logger) {
|
func resetPrivValidatorLocal(privValFile string, logger log.Logger) {
|
||||||
// Get PrivValidator
|
// Get PrivValidator
|
||||||
var privValidator types.PrivValidator
|
|
||||||
if _, err := os.Stat(privValFile); err == nil {
|
if _, err := os.Stat(privValFile); err == nil {
|
||||||
privValidator = types.LoadPrivValidator(privValFile)
|
privValidator := types.LoadPrivValidatorFS(privValFile)
|
||||||
privValidator.Reset()
|
privValidator.Reset()
|
||||||
logger.Info("Reset PrivValidator", "file", privValFile)
|
logger.Info("Reset PrivValidator", "file", privValFile)
|
||||||
} else {
|
} else {
|
||||||
privValidator = types.GenPrivValidator()
|
privValidator := types.GenPrivValidatorFS(privValFile)
|
||||||
privValidator.SetFile(privValFile)
|
|
||||||
privValidator.Save()
|
privValidator.Save()
|
||||||
logger.Info("Generated PrivValidator", "file", privValFile)
|
logger.Info("Generated PrivValidator", "file", privValFile)
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func AddNodeFlags(cmd *cobra.Command) {
|
|||||||
type FuncSignerAndApp func(*cfg.Config) (types.PrivValidator, proxy.ClientCreator)
|
type FuncSignerAndApp func(*cfg.Config) (types.PrivValidator, proxy.ClientCreator)
|
||||||
|
|
||||||
func DefaultSignerAndApp(config *cfg.Config) (types.PrivValidator, proxy.ClientCreator) {
|
func DefaultSignerAndApp(config *cfg.Config) (types.PrivValidator, proxy.ClientCreator) {
|
||||||
privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile())
|
privValidator := types.LoadOrGenPrivValidatorFS(config.PrivValidatorFile())
|
||||||
clientCreator := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir())
|
clientCreator := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir())
|
||||||
return privValidator, clientCreator
|
return privValidator, clientCreator
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ var ShowValidatorCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func showValidator(cmd *cobra.Command, args []string) {
|
func showValidator(cmd *cobra.Command, args []string) {
|
||||||
privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile())
|
privValidator := types.LoadOrGenPrivValidatorFS(config.PrivValidatorFile())
|
||||||
pubKeyJSONBytes, _ := data.ToJSON(privValidator.PubKey)
|
pubKeyJSONBytes, _ := data.ToJSON(privValidator.PubKey)
|
||||||
fmt.Println(string(pubKeyJSONBytes))
|
fmt.Println(string(pubKeyJSONBytes))
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ func testnetFiles(cmd *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
// Read priv_validator.json to populate vals
|
// Read priv_validator.json to populate vals
|
||||||
privValFile := path.Join(dataDir, mach, "priv_validator.json")
|
privValFile := path.Join(dataDir, mach, "priv_validator.json")
|
||||||
privVal := types.LoadPrivValidator(privValFile)
|
privVal := types.LoadPrivValidatorFS(privValFile)
|
||||||
genVals[i] = types.GenesisValidator{
|
genVals[i] = types.GenesisValidator{
|
||||||
PubKey: privVal.PubKey(),
|
PubKey: privVal.PubKey(),
|
||||||
Power: 1,
|
Power: 1,
|
||||||
@ -87,7 +87,6 @@ func ensurePrivValidator(file string) {
|
|||||||
if cmn.FileExists(file) {
|
if cmn.FileExists(file) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
privValidator := types.GenPrivValidator()
|
privValidator := types.GenPrivValidatorFS(file)
|
||||||
privValidator.SetFile(file)
|
|
||||||
privValidator.Save()
|
privValidator.Save()
|
||||||
}
|
}
|
||||||
|
@ -368,9 +368,8 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF
|
|||||||
if i < nValidators {
|
if i < nValidators {
|
||||||
privVal = privVals[i]
|
privVal = privVals[i]
|
||||||
} else {
|
} else {
|
||||||
privVal = types.GenPrivValidator()
|
|
||||||
_, tempFilePath := Tempfile("priv_validator_")
|
_, tempFilePath := Tempfile("priv_validator_")
|
||||||
privVal.SetFile(tempFilePath)
|
privVal = types.GenPrivValidator(tempFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
css[i] = newConsensusStateWithConfig(thisConfig, state, privVal, appFunc())
|
css[i] = newConsensusStateWithConfig(thisConfig, state, privVal, appFunc())
|
||||||
|
@ -60,7 +60,7 @@ type Node struct {
|
|||||||
|
|
||||||
func NewNodeDefault(config *cfg.Config, logger log.Logger) *Node {
|
func NewNodeDefault(config *cfg.Config, logger log.Logger) *Node {
|
||||||
// Get PrivValidator
|
// Get PrivValidator
|
||||||
privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile())
|
privValidator := types.LoadOrGenPrivValidatorFS(config.PrivValidatorFile())
|
||||||
return NewNode(config, privValidator,
|
return NewNode(config, privValidator,
|
||||||
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), logger)
|
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), logger)
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ func NewNode(config *cfg.Config, privValidator types.PrivValidator, clientCreato
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log whether this node is a validator or an observer
|
// Log whether this node is a validator or an observer
|
||||||
if state.Validators.HasAddress(privValidator.PubKey().Address()) {
|
if state.Validators.HasAddress(privValidator.Address()) {
|
||||||
consensusLogger.Info("This node is a validator")
|
consensusLogger.Info("This node is a validator")
|
||||||
} else {
|
} else {
|
||||||
consensusLogger.Info("This node is not a validator")
|
consensusLogger.Info("This node is not a validator")
|
||||||
|
@ -34,37 +34,7 @@ func voteToStep(vote *Vote) int8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signer is an interface that defines how to sign votes.
|
// PrivValidator defines the functionality of a local Tendermint validator.
|
||||||
// It is the caller's duty to verify the msg before calling Sign,
|
|
||||||
// eg. to avoid double signing.
|
|
||||||
// Currently, the only callers are SignVote and SignProposal.
|
|
||||||
type Signer interface {
|
|
||||||
PubKey() crypto.PubKey
|
|
||||||
Sign(msg []byte) (crypto.Signature, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultSigner implements Signer.
|
|
||||||
// It uses a standard crypto.PrivKey.
|
|
||||||
type DefaultSigner struct {
|
|
||||||
PrivKey crypto.PrivKey `json:"priv_key"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDefaultSigner returns an instance of DefaultSigner.
|
|
||||||
func NewDefaultSigner(priv crypto.PrivKey) *DefaultSigner {
|
|
||||||
return &DefaultSigner{PrivKey: priv}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign implements Signer. It signs the byte slice with a private key.
|
|
||||||
func (ds *DefaultSigner) Sign(msg []byte) (crypto.Signature, error) {
|
|
||||||
return ds.PrivKey.Sign(msg), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PubKey implements Signer. It should return the public key that corresponds
|
|
||||||
// to the private key used for signing.
|
|
||||||
func (ds *DefaultSigner) PubKey() crypto.PubKey {
|
|
||||||
return ds.PrivKey.PubKey()
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrivValidator interface {
|
type PrivValidator interface {
|
||||||
Address() data.Bytes // redundant since .PubKey().Address()
|
Address() data.Bytes // redundant since .PubKey().Address()
|
||||||
PubKey() crypto.PubKey
|
PubKey() crypto.PubKey
|
||||||
@ -72,60 +42,45 @@ type PrivValidator interface {
|
|||||||
SignVote(chainID string, vote *Vote) error
|
SignVote(chainID string, vote *Vote) error
|
||||||
SignProposal(chainID string, proposal *Proposal) error
|
SignProposal(chainID string, proposal *Proposal) error
|
||||||
SignHeartbeat(chainID string, heartbeat *Heartbeat) error
|
SignHeartbeat(chainID string, heartbeat *Heartbeat) error
|
||||||
|
|
||||||
Reset()
|
|
||||||
|
|
||||||
SetFile(file string)
|
|
||||||
Save()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultPrivValidator implements the functionality for signing blocks.
|
// PrivValidatorFS implements PrivValidator using data persisted to disk
|
||||||
type DefaultPrivValidator struct {
|
// to prevent double signing. The Signer itself can be mutated to use
|
||||||
Info PrivValidatorInfo `json:"info"`
|
// something besides the default, for instance a hardware signer.
|
||||||
Signer *DefaultSigner `json:"signer"`
|
type PrivValidatorFS struct {
|
||||||
|
ID ValidatorID `json:"id"`
|
||||||
|
Signer Signer `json:"signer"`
|
||||||
|
|
||||||
|
// mutable state to be persisted to disk
|
||||||
|
// after each signature to prevent double signing
|
||||||
|
mtx sync.Mutex
|
||||||
|
Info LastSignedInfo `json:"info"`
|
||||||
|
|
||||||
// For persistence.
|
// For persistence.
|
||||||
// Overloaded for testing.
|
// Overloaded for testing.
|
||||||
filePath string
|
filePath string
|
||||||
mtx sync.Mutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pv *DefaultPrivValidator) Address() data.Bytes {
|
// LoadOrGenPrivValidatorFS loads a PrivValidatorFS from the given filePath
|
||||||
return pv.Info.Address
|
// or else generates a new one and saves it to the filePath.
|
||||||
}
|
func LoadOrGenPrivValidatorFS(filePath string) *PrivValidatorFS {
|
||||||
|
var PrivValidatorFS *PrivValidatorFS
|
||||||
func (pv *DefaultPrivValidator) PubKey() crypto.PubKey {
|
|
||||||
return pv.Info.PubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrivValidatorInfo struct {
|
|
||||||
Address data.Bytes `json:"address"`
|
|
||||||
PubKey crypto.PubKey `json:"pub_key"`
|
|
||||||
LastHeight int `json:"last_height"`
|
|
||||||
LastRound int `json:"last_round"`
|
|
||||||
LastStep int8 `json:"last_step"`
|
|
||||||
LastSignature crypto.Signature `json:"last_signature,omitempty"` // so we dont lose signatures
|
|
||||||
LastSignBytes data.Bytes `json:"last_signbytes,omitempty"` // so we dont lose signatures
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadOrGenPrivValidator(filePath string) *DefaultPrivValidator {
|
|
||||||
var privValidator *DefaultPrivValidator
|
|
||||||
if _, err := os.Stat(filePath); err == nil {
|
if _, err := os.Stat(filePath); err == nil {
|
||||||
privValidator = LoadPrivValidator(filePath)
|
PrivValidatorFS = LoadPrivValidatorFS(filePath)
|
||||||
} else {
|
} else {
|
||||||
privValidator = GenPrivValidator()
|
PrivValidatorFS = GenPrivValidatorFS(filePath)
|
||||||
privValidator.SetFile(filePath)
|
PrivValidatorFS.Save()
|
||||||
privValidator.Save()
|
|
||||||
}
|
}
|
||||||
return privValidator
|
return PrivValidatorFS
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadPrivValidator(filePath string) *DefaultPrivValidator {
|
// LoadPrivValidatorFS loads a PrivValidatorFS from the filePath.
|
||||||
|
func LoadPrivValidatorFS(filePath string) *PrivValidatorFS {
|
||||||
privValJSONBytes, err := ioutil.ReadFile(filePath)
|
privValJSONBytes, err := ioutil.ReadFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Exit(err.Error())
|
Exit(err.Error())
|
||||||
}
|
}
|
||||||
privVal := DefaultPrivValidator{}
|
privVal := PrivValidatorFS{}
|
||||||
err = json.Unmarshal(privValJSONBytes, &privVal)
|
err = json.Unmarshal(privValJSONBytes, &privVal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Exit(Fmt("Error reading PrivValidator from %v: %v\n", filePath, err))
|
Exit(Fmt("Error reading PrivValidator from %v: %v\n", filePath, err))
|
||||||
@ -135,56 +90,58 @@ func LoadPrivValidator(filePath string) *DefaultPrivValidator {
|
|||||||
return &privVal
|
return &privVal
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates a new validator with private key.
|
// GenPrivValidatorFS generates a new validator with randomly generated private key
|
||||||
func GenPrivValidator() *DefaultPrivValidator {
|
// and sets the filePath, but does not call Save().
|
||||||
|
func GenPrivValidatorFS(filePath string) *PrivValidatorFS {
|
||||||
privKey := crypto.GenPrivKeyEd25519().Wrap()
|
privKey := crypto.GenPrivKeyEd25519().Wrap()
|
||||||
pubKey := privKey.PubKey()
|
return &PrivValidatorFS{
|
||||||
return &DefaultPrivValidator{
|
ID: ValidatorID{privKey.PubKey().Address(), privKey.PubKey()},
|
||||||
Info: PrivValidatorInfo{
|
Info: LastSignedInfo{
|
||||||
Address: pubKey.Address(),
|
|
||||||
PubKey: pubKey,
|
|
||||||
LastStep: stepNone,
|
LastStep: stepNone,
|
||||||
},
|
},
|
||||||
Signer: NewDefaultSigner(privKey),
|
Signer: NewDefaultSigner(privKey),
|
||||||
filePath: "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadPrivValidatorWithSigner instantiates a private validator with a custom
|
|
||||||
// signer object. Tendermint tracks state in the PrivValidator that might be
|
|
||||||
// saved to disk. Please supply a filepath where Tendermint can save the
|
|
||||||
// private validator.
|
|
||||||
func LoadPrivValidatorWithSigner(signer *DefaultSigner, filePath string) *DefaultPrivValidator {
|
|
||||||
return &DefaultPrivValidator{
|
|
||||||
Info: PrivValidatorInfo{
|
|
||||||
Address: signer.PubKey().Address(),
|
|
||||||
PubKey: signer.PubKey(),
|
|
||||||
LastStep: stepNone,
|
|
||||||
},
|
|
||||||
Signer: signer,
|
|
||||||
filePath: filePath,
|
filePath: filePath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overwrite address and pubkey for convenience
|
// LoadPrivValidatorWithSigner loads a PrivValidatorFS with a custom
|
||||||
/*func (privVal *DefaultPrivValidator) setPubKeyAndAddress() {
|
// signer object. The PrivValidatorFS handles double signing prevention by persisting
|
||||||
privVal.PubKey = privVal.Signer.PubKey()
|
// data to the filePath, while the Signer handles the signing.
|
||||||
privVal.Address = privVal.PubKey.Address()
|
// If the filePath does not exist, the PrivValidatorFS must be created manually and saved.
|
||||||
}*/
|
func LoadPrivValidatorFSWithSigner(filePath string, signerFunc func(ValidatorID) Signer) *PrivValidatorFS {
|
||||||
|
privValJSONBytes, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
Exit(err.Error())
|
||||||
|
}
|
||||||
|
privVal := PrivValidatorFS{}
|
||||||
|
err = json.Unmarshal(privValJSONBytes, &privVal)
|
||||||
|
if err != nil {
|
||||||
|
Exit(Fmt("Error reading PrivValidator from %v: %v\n", filePath, err))
|
||||||
|
}
|
||||||
|
|
||||||
func (privVal *DefaultPrivValidator) SetFile(filePath string) {
|
|
||||||
privVal.mtx.Lock()
|
|
||||||
defer privVal.mtx.Unlock()
|
|
||||||
privVal.filePath = filePath
|
privVal.filePath = filePath
|
||||||
|
privVal.Signer = signerFunc(privVal.ID)
|
||||||
|
return &privVal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (privVal *DefaultPrivValidator) Save() {
|
// Address returns the address of the validator.
|
||||||
|
func (pv *PrivValidatorFS) Address() data.Bytes {
|
||||||
|
return pv.ID.Address
|
||||||
|
}
|
||||||
|
|
||||||
|
// PubKey returns the public key of the validator.
|
||||||
|
func (pv *PrivValidatorFS) PubKey() crypto.PubKey {
|
||||||
|
return pv.ID.PubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save persists the PrivValidatorFS to disk.
|
||||||
|
func (privVal *PrivValidatorFS) Save() {
|
||||||
privVal.mtx.Lock()
|
privVal.mtx.Lock()
|
||||||
defer privVal.mtx.Unlock()
|
defer privVal.mtx.Unlock()
|
||||||
privVal.save()
|
privVal.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (privVal *DefaultPrivValidator) save() {
|
func (privVal *PrivValidatorFS) save() {
|
||||||
if privVal.filePath == "" {
|
if privVal.filePath == "" {
|
||||||
PanicSanity("Cannot save PrivValidator: filePath not set")
|
PanicSanity("Cannot save PrivValidator: filePath not set")
|
||||||
}
|
}
|
||||||
@ -200,8 +157,9 @@ func (privVal *DefaultPrivValidator) save() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset resets all fields in the PrivValidatorFS.Info.
|
||||||
// NOTE: Unsafe!
|
// NOTE: Unsafe!
|
||||||
func (privVal *DefaultPrivValidator) Reset() {
|
func (privVal *PrivValidatorFS) Reset() {
|
||||||
privVal.Info.LastHeight = 0
|
privVal.Info.LastHeight = 0
|
||||||
privVal.Info.LastRound = 0
|
privVal.Info.LastRound = 0
|
||||||
privVal.Info.LastStep = 0
|
privVal.Info.LastStep = 0
|
||||||
@ -210,11 +168,8 @@ func (privVal *DefaultPrivValidator) Reset() {
|
|||||||
privVal.Save()
|
privVal.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (privVal *DefaultPrivValidator) GetAddress() []byte {
|
// SignVote signs a canonical representation of the vote, along with the chainID.
|
||||||
return privVal.Address()
|
func (privVal *PrivValidatorFS) SignVote(chainID string, vote *Vote) error {
|
||||||
}
|
|
||||||
|
|
||||||
func (privVal *DefaultPrivValidator) SignVote(chainID string, vote *Vote) error {
|
|
||||||
privVal.mtx.Lock()
|
privVal.mtx.Lock()
|
||||||
defer privVal.mtx.Unlock()
|
defer privVal.mtx.Unlock()
|
||||||
signature, err := privVal.signBytesHRS(vote.Height, vote.Round, voteToStep(vote), SignBytes(chainID, vote))
|
signature, err := privVal.signBytesHRS(vote.Height, vote.Round, voteToStep(vote), SignBytes(chainID, vote))
|
||||||
@ -225,7 +180,8 @@ func (privVal *DefaultPrivValidator) SignVote(chainID string, vote *Vote) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (privVal *DefaultPrivValidator) SignProposal(chainID string, proposal *Proposal) error {
|
// SignProposal signs a canonical representation of the proposal, along with the chainID.
|
||||||
|
func (privVal *PrivValidatorFS) SignProposal(chainID string, proposal *Proposal) error {
|
||||||
privVal.mtx.Lock()
|
privVal.mtx.Lock()
|
||||||
defer privVal.mtx.Unlock()
|
defer privVal.mtx.Unlock()
|
||||||
signature, err := privVal.signBytesHRS(proposal.Height, proposal.Round, stepPropose, SignBytes(chainID, proposal))
|
signature, err := privVal.signBytesHRS(proposal.Height, proposal.Round, stepPropose, SignBytes(chainID, proposal))
|
||||||
@ -236,8 +192,17 @@ func (privVal *DefaultPrivValidator) SignProposal(chainID string, proposal *Prop
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SignHeartbeat signs a canonical representation of the heartbeat, along with the chainID.
|
||||||
|
func (privVal *PrivValidatorFS) SignHeartbeat(chainID string, heartbeat *Heartbeat) error {
|
||||||
|
privVal.mtx.Lock()
|
||||||
|
defer privVal.mtx.Unlock()
|
||||||
|
var err error
|
||||||
|
heartbeat.Signature, err = privVal.Signer.Sign(SignBytes(chainID, heartbeat))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// check if there's a regression. Else sign and write the hrs+signature to disk
|
// check if there's a regression. Else sign and write the hrs+signature to disk
|
||||||
func (privVal *DefaultPrivValidator) signBytesHRS(height, round int, step int8, signBytes []byte) (crypto.Signature, error) {
|
func (privVal *PrivValidatorFS) signBytesHRS(height, round int, step int8, signBytes []byte) (crypto.Signature, error) {
|
||||||
sig := crypto.Signature{}
|
sig := crypto.Signature{}
|
||||||
info := privVal.Info
|
info := privVal.Info
|
||||||
// If height regression, err
|
// If height regression, err
|
||||||
@ -287,32 +252,68 @@ func (privVal *DefaultPrivValidator) signBytesHRS(height, round int, step int8,
|
|||||||
privVal.save()
|
privVal.save()
|
||||||
|
|
||||||
return sig, nil
|
return sig, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (privVal *DefaultPrivValidator) SignHeartbeat(chainID string, heartbeat *Heartbeat) error {
|
// String returns a string representation of the PrivValidatorFS.
|
||||||
privVal.mtx.Lock()
|
func (privVal *PrivValidatorFS) String() string {
|
||||||
defer privVal.mtx.Unlock()
|
|
||||||
var err error
|
|
||||||
heartbeat.Signature, err = privVal.Signer.Sign(SignBytes(chainID, heartbeat))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (privVal *DefaultPrivValidator) String() string {
|
|
||||||
info := privVal.Info
|
info := privVal.Info
|
||||||
return fmt.Sprintf("PrivValidator{%v LH:%v, LR:%v, LS:%v}", info.Address, info.LastHeight, info.LastRound, info.LastStep)
|
return fmt.Sprintf("PrivValidator{%v LH:%v, LR:%v, LS:%v}", privVal.Address(), info.LastHeight, info.LastRound, info.LastStep)
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
type PrivValidatorsByAddress []*DefaultPrivValidator
|
// ValidatorID contains the identity of the validator.
|
||||||
|
type ValidatorID struct {
|
||||||
|
Address data.Bytes `json:"address"`
|
||||||
|
PubKey crypto.PubKey `json:"pub_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LastSignedInfo contains information about the latest
|
||||||
|
// data signed by a validator to help prevent double signing.
|
||||||
|
type LastSignedInfo struct {
|
||||||
|
LastHeight int `json:"last_height"`
|
||||||
|
LastRound int `json:"last_round"`
|
||||||
|
LastStep int8 `json:"last_step"`
|
||||||
|
LastSignature crypto.Signature `json:"last_signature,omitempty"` // so we dont lose signatures
|
||||||
|
LastSignBytes data.Bytes `json:"last_signbytes,omitempty"` // so we dont lose signatures
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signer is an interface that defines how to sign messages.
|
||||||
|
// It is the caller's duty to verify the msg before calling Sign,
|
||||||
|
// eg. to avoid double signing.
|
||||||
|
// Currently, the only callers are SignVote, SignProposal, and SignHeartbeat.
|
||||||
|
type Signer interface {
|
||||||
|
Sign(msg []byte) (crypto.Signature, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultSigner implements Signer.
|
||||||
|
// It uses a standard, unencrypted crypto.PrivKey.
|
||||||
|
type DefaultSigner struct {
|
||||||
|
PrivKey crypto.PrivKey `json:"priv_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultSigner returns an instance of DefaultSigner.
|
||||||
|
func NewDefaultSigner(priv crypto.PrivKey) *DefaultSigner {
|
||||||
|
return &DefaultSigner{
|
||||||
|
PrivKey: priv,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign implements Signer. It signs the byte slice with a private key.
|
||||||
|
func (ds *DefaultSigner) Sign(msg []byte) (crypto.Signature, error) {
|
||||||
|
return ds.PrivKey.Sign(msg), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
|
||||||
|
type PrivValidatorsByAddress []*PrivValidatorFS
|
||||||
|
|
||||||
func (pvs PrivValidatorsByAddress) Len() int {
|
func (pvs PrivValidatorsByAddress) Len() int {
|
||||||
return len(pvs)
|
return len(pvs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pvs PrivValidatorsByAddress) Less(i, j int) bool {
|
func (pvs PrivValidatorsByAddress) Less(i, j int) bool {
|
||||||
return bytes.Compare(pvs[i].Info.Address, pvs[j].Info.Address) == -1
|
return bytes.Compare(pvs[i].Address(), pvs[j].Address()) == -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pvs PrivValidatorsByAddress) Swap(i, j int) {
|
func (pvs PrivValidatorsByAddress) Swap(i, j int) {
|
||||||
|
@ -106,10 +106,9 @@ func (vc validatorCodec) Compare(o1 interface{}, o2 interface{}) int {
|
|||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
// For testing...
|
// For testing...
|
||||||
|
|
||||||
func RandValidator(randPower bool, minPower int64) (*Validator, *DefaultPrivValidator) {
|
func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidatorFS) {
|
||||||
privVal := GenPrivValidator()
|
|
||||||
_, tempFilePath := cmn.Tempfile("priv_validator_")
|
_, tempFilePath := cmn.Tempfile("priv_validator_")
|
||||||
privVal.SetFile(tempFilePath)
|
privVal := GenPrivValidatorFS(tempFilePath)
|
||||||
votePower := minPower
|
votePower := minPower
|
||||||
if randPower {
|
if randPower {
|
||||||
votePower += int64(cmn.RandUint32())
|
votePower += int64(cmn.RandUint32())
|
||||||
|
@ -369,9 +369,9 @@ func (ac accumComparable) Less(o interface{}) bool {
|
|||||||
// For testing
|
// For testing
|
||||||
|
|
||||||
// NOTE: PrivValidator are in order.
|
// NOTE: PrivValidator are in order.
|
||||||
func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []*DefaultPrivValidator) {
|
func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []*PrivValidatorFS) {
|
||||||
vals := make([]*Validator, numValidators)
|
vals := make([]*Validator, numValidators)
|
||||||
privValidators := make([]*DefaultPrivValidator, numValidators)
|
privValidators := make([]*PrivValidatorFS, numValidators)
|
||||||
for i := 0; i < numValidators; i++ {
|
for i := 0; i < numValidators; i++ {
|
||||||
val, privValidator := RandValidator(false, votingPower)
|
val, privValidator := RandValidator(false, votingPower)
|
||||||
vals[i] = val
|
vals[i] = val
|
||||||
|
Reference in New Issue
Block a user