@ -211,18 +211,18 @@ func LoadPrivValidatorFSWithSigner(filePath string, signerFunc func(PrivValidato
}
}
// Save persists the PrivValidatorFS to disk.
// Save persists the PrivValidatorFS to disk.
func ( pri vVal * PrivValidatorFS ) Save ( ) {
pri vVal . mtx . Lock ( )
defer pri vVal . mtx . Unlock ( )
pri vVal . save ( )
func ( pv * PrivValidatorFS ) Save ( ) {
pv . mtx . Lock ( )
defer pv . mtx . Unlock ( )
pv . save ( )
}
}
func ( pri vVal * PrivValidatorFS ) save ( ) {
outFile := pri vVal . filePath
func ( pv * PrivValidatorFS ) save ( ) {
outFile := pv . filePath
if outFile == "" {
if outFile == "" {
panic ( "Cannot save PrivValidator: filePath not set" )
panic ( "Cannot save PrivValidator: filePath not set" )
}
}
jsonBytes , err := json . Marshal ( pri vVal )
jsonBytes , err := json . Marshal ( pv )
if err != nil {
if err != nil {
panic ( err )
panic ( err )
}
}
@ -234,22 +234,22 @@ func (privVal *PrivValidatorFS) save() {
// Reset resets all fields in the PrivValidatorFS.
// Reset resets all fields in the PrivValidatorFS.
// NOTE: Unsafe!
// NOTE: Unsafe!
func ( pri vVal * PrivValidatorFS ) Reset ( ) {
func ( pv * PrivValidatorFS ) Reset ( ) {
var sig crypto . Signature
var sig crypto . Signature
pri vVal . LastHeight = 0
pri vVal . LastRound = 0
pri vVal . LastStep = 0
pri vVal . LastSignature = sig
pri vVal . LastSignBytes = nil
pri vVal . Save ( )
pv . LastHeight = 0
pv . LastRound = 0
pv . LastStep = 0
pv . LastSignature = sig
pv . LastSignBytes = nil
pv . Save ( )
}
}
// SignVote signs a canonical representation of the vote, along with the
// SignVote signs a canonical representation of the vote, along with the
// chainID. Implements PrivValidator.
// chainID. Implements PrivValidator.
func ( pri vVal * PrivValidatorFS ) SignVote ( chainID string , vote * Vote ) error {
pri vVal . mtx . Lock ( )
defer pri vVal . mtx . Unlock ( )
if err := pri vVal . signVote ( chainID , vote ) ; err != nil {
func ( pv * PrivValidatorFS ) SignVote ( chainID string , vote * Vote ) error {
pv . mtx . Lock ( )
defer pv . mtx . Unlock ( )
if err := pv . signVote ( chainID , vote ) ; err != nil {
return errors . New ( cmn . Fmt ( "Error signing vote: %v" , err ) )
return errors . New ( cmn . Fmt ( "Error signing vote: %v" , err ) )
}
}
return nil
return nil
@ -257,32 +257,32 @@ func (privVal *PrivValidatorFS) SignVote(chainID string, vote *Vote) error {
// SignProposal signs a canonical representation of the proposal, along with
// SignProposal signs a canonical representation of the proposal, along with
// the chainID. Implements PrivValidator.
// the chainID. Implements PrivValidator.
func ( pri vVal * PrivValidatorFS ) SignProposal ( chainID string , proposal * Proposal ) error {
pri vVal . mtx . Lock ( )
defer pri vVal . mtx . Unlock ( )
if err := pri vVal . signProposal ( chainID , proposal ) ; err != nil {
func ( pv * PrivValidatorFS ) SignProposal ( chainID string , proposal * Proposal ) error {
pv . mtx . Lock ( )
defer pv . mtx . Unlock ( )
if err := pv . signProposal ( chainID , proposal ) ; err != nil {
return fmt . Errorf ( "Error signing proposal: %v" , err )
return fmt . Errorf ( "Error signing proposal: %v" , err )
}
}
return nil
return nil
}
}
// returns error if HRS regression or no LastSignBytes. returns true if HRS is unchanged
// returns error if HRS regression or no LastSignBytes. returns true if HRS is unchanged
func ( pri vVal * PrivValidatorFS ) checkHRS ( height int64 , round int , step int8 ) ( bool , error ) {
if pri vVal . LastHeight > height {
func ( pv * PrivValidatorFS ) checkHRS ( height int64 , round int , step int8 ) ( bool , error ) {
if pv . LastHeight > height {
return false , errors . New ( "Height regression" )
return false , errors . New ( "Height regression" )
}
}
if pri vVal . LastHeight == height {
if pri vVal . LastRound > round {
if pv . LastHeight == height {
if pv . LastRound > round {
return false , errors . New ( "Round regression" )
return false , errors . New ( "Round regression" )
}
}
if pri vVal . LastRound == round {
if pri vVal . LastStep > step {
if pv . LastRound == round {
if pv . LastStep > step {
return false , errors . New ( "Step regression" )
return false , errors . New ( "Step regression" )
} else if pri vVal . LastStep == step {
if pri vVal . LastSignBytes != nil {
if pri vVal . LastSignature . Empty ( ) {
} else if pv . LastStep == step {
if pv . LastSignBytes != nil {
if pv . LastSignature . Empty ( ) {
panic ( "privVal: LastSignature is nil but LastSignBytes is not!" )
panic ( "privVal: LastSignature is nil but LastSignBytes is not!" )
}
}
return true , nil
return true , nil
@ -297,11 +297,11 @@ func (privVal *PrivValidatorFS) checkHRS(height int64, round int, step int8) (bo
// signVote checks if the vote is good to sign and sets the vote signature.
// signVote checks if the vote is good to sign and sets the vote signature.
// It may need to set the timestamp as well if the vote is otherwise the same as
// It may need to set the timestamp as well if the vote is otherwise the same as
// a previously signed vote (ie. we crashed after signing but before the vote hit the WAL).
// a previously signed vote (ie. we crashed after signing but before the vote hit the WAL).
func ( pri vVal * PrivValidatorFS ) signVote ( chainID string , vote * Vote ) error {
func ( pv * PrivValidatorFS ) signVote ( chainID string , vote * Vote ) error {
height , round , step := vote . Height , vote . Round , voteToStep ( vote )
height , round , step := vote . Height , vote . Round , voteToStep ( vote )
signBytes := vote . SignBytes ( chainID )
signBytes := vote . SignBytes ( chainID )
sameHRS , err := pri vVal . checkHRS ( height , round , step )
sameHRS , err := pv . checkHRS ( height , round , step )
if err != nil {
if err != nil {
return err
return err
}
}
@ -312,11 +312,11 @@ func (privVal *PrivValidatorFS) signVote(chainID string, vote *Vote) error {
// If they only differ by timestamp, use last timestamp and signature
// If they only differ by timestamp, use last timestamp and signature
// Otherwise, return error
// Otherwise, return error
if sameHRS {
if sameHRS {
if bytes . Equal ( signBytes , pri vVal . LastSignBytes ) {
vote . Signature = pri vVal . LastSignature
} else if timestamp , ok := checkVotesOnlyDifferByTimestamp ( pri vVal . LastSignBytes , signBytes ) ; ok {
if bytes . Equal ( signBytes , pv . LastSignBytes ) {
vote . Signature = pv . LastSignature
} else if timestamp , ok := checkVotesOnlyDifferByTimestamp ( pv . LastSignBytes , signBytes ) ; ok {
vote . Timestamp = timestamp
vote . Timestamp = timestamp
vote . Signature = pri vVal . LastSignature
vote . Signature = pv . LastSignature
} else {
} else {
err = fmt . Errorf ( "Conflicting data" )
err = fmt . Errorf ( "Conflicting data" )
}
}
@ -324,11 +324,11 @@ func (privVal *PrivValidatorFS) signVote(chainID string, vote *Vote) error {
}
}
// It passed the checks. Sign the vote
// It passed the checks. Sign the vote
sig , err := pri vVal . Sign ( signBytes )
sig , err := pv . Sign ( signBytes )
if err != nil {
if err != nil {
return err
return err
}
}
pri vVal . saveSigned ( height , round , step , signBytes , sig )
pv . saveSigned ( height , round , step , signBytes , sig )
vote . Signature = sig
vote . Signature = sig
return nil
return nil
}
}
@ -336,11 +336,11 @@ func (privVal *PrivValidatorFS) signVote(chainID string, vote *Vote) error {
// signProposal checks if the proposal is good to sign and sets the proposal signature.
// signProposal checks if the proposal is good to sign and sets the proposal signature.
// It may need to set the timestamp as well if the proposal is otherwise the same as
// It may need to set the timestamp as well if the proposal is otherwise the same as
// a previously signed proposal ie. we crashed after signing but before the proposal hit the WAL).
// a previously signed proposal ie. we crashed after signing but before the proposal hit the WAL).
func ( pri vVal * PrivValidatorFS ) signProposal ( chainID string , proposal * Proposal ) error {
func ( pv * PrivValidatorFS ) signProposal ( chainID string , proposal * Proposal ) error {
height , round , step := proposal . Height , proposal . Round , stepPropose
height , round , step := proposal . Height , proposal . Round , stepPropose
signBytes := proposal . SignBytes ( chainID )
signBytes := proposal . SignBytes ( chainID )
sameHRS , err := pri vVal . checkHRS ( height , round , step )
sameHRS , err := pv . checkHRS ( height , round , step )
if err != nil {
if err != nil {
return err
return err
}
}
@ -351,11 +351,11 @@ func (privVal *PrivValidatorFS) signProposal(chainID string, proposal *Proposal)
// If they only differ by timestamp, use last timestamp and signature
// If they only differ by timestamp, use last timestamp and signature
// Otherwise, return error
// Otherwise, return error
if sameHRS {
if sameHRS {
if bytes . Equal ( signBytes , pri vVal . LastSignBytes ) {
proposal . Signature = pri vVal . LastSignature
} else if timestamp , ok := checkProposalsOnlyDifferByTimestamp ( pri vVal . LastSignBytes , signBytes ) ; ok {
if bytes . Equal ( signBytes , pv . LastSignBytes ) {
proposal . Signature = pv . LastSignature
} else if timestamp , ok := checkProposalsOnlyDifferByTimestamp ( pv . LastSignBytes , signBytes ) ; ok {
proposal . Timestamp = timestamp
proposal . Timestamp = timestamp
proposal . Signature = pri vVal . LastSignature
proposal . Signature = pv . LastSignature
} else {
} else {
err = fmt . Errorf ( "Conflicting data" )
err = fmt . Errorf ( "Conflicting data" )
}
}
@ -363,40 +363,40 @@ func (privVal *PrivValidatorFS) signProposal(chainID string, proposal *Proposal)
}
}
// It passed the checks. Sign the proposal
// It passed the checks. Sign the proposal
sig , err := pri vVal . Sign ( signBytes )
sig , err := pv . Sign ( signBytes )
if err != nil {
if err != nil {
return err
return err
}
}
pri vVal . saveSigned ( height , round , step , signBytes , sig )
pv . saveSigned ( height , round , step , signBytes , sig )
proposal . Signature = sig
proposal . Signature = sig
return nil
return nil
}
}
// Persist height/round/step and signature
// Persist height/round/step and signature
func ( pri vVal * PrivValidatorFS ) saveSigned ( height int64 , round int , step int8 ,
func ( pv * PrivValidatorFS ) saveSigned ( height int64 , round int , step int8 ,
signBytes [ ] byte , sig crypto . Signature ) {
signBytes [ ] byte , sig crypto . Signature ) {
pri vVal . LastHeight = height
pri vVal . LastRound = round
pri vVal . LastStep = step
pri vVal . LastSignature = sig
pri vVal . LastSignBytes = signBytes
pri vVal . save ( )
pv . LastHeight = height
pv . LastRound = round
pv . LastStep = step
pv . LastSignature = sig
pv . LastSignBytes = signBytes
pv . save ( )
}
}
// SignHeartbeat signs a canonical representation of the heartbeat, along with the chainID.
// SignHeartbeat signs a canonical representation of the heartbeat, along with the chainID.
// Implements PrivValidator.
// Implements PrivValidator.
func ( pri vVal * PrivValidatorFS ) SignHeartbeat ( chainID string , heartbeat * Heartbeat ) error {
pri vVal . mtx . Lock ( )
defer pri vVal . mtx . Unlock ( )
func ( pv * PrivValidatorFS ) SignHeartbeat ( chainID string , heartbeat * Heartbeat ) error {
pv . mtx . Lock ( )
defer pv . mtx . Unlock ( )
var err error
var err error
heartbeat . Signature , err = pri vVal . Sign ( heartbeat . SignBytes ( chainID ) )
heartbeat . Signature , err = pv . Sign ( heartbeat . SignBytes ( chainID ) )
return err
return err
}
}
// String returns a string representation of the PrivValidatorFS.
// String returns a string representation of the PrivValidatorFS.
func ( pri vVal * PrivValidatorFS ) String ( ) string {
return fmt . Sprintf ( "PrivValidator{%v LH:%v, LR:%v, LS:%v}" , pri vVal . GetAddress ( ) , pri vVal . LastHeight , pri vVal . LastRound , pri vVal . LastStep )
func ( pv * PrivValidatorFS ) String ( ) string {
return fmt . Sprintf ( "PrivValidator{%v LH:%v, LR:%v, LS:%v}" , pv . GetAddress ( ) , pv . LastHeight , pv . LastRound , pv . LastStep )
}
}
//-------------------------------------
//-------------------------------------