func LoadOrGenFilePV(filePath string) *FilePV {
	var pv *FilePV
	if cmn.FileExists(filePath) {
		pv = LoadFilePV(filePath)
	} else {
		pv = GenFilePV(filePath)
		pv.Save()
	}
	return pv
}
LoadOrGenFilePV loads a FilePV from the given filePath
or else generates a new one and saves it to the filePath.
package privval
import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"sync"
	"time"
	"github.com/tendermint/tendermint/crypto"
	"github.com/tendermint/tendermint/crypto/ed25519"
	cmn "github.com/tendermint/tendermint/libs/common"
	"github.com/tendermint/tendermint/types"
)
const (
	stepNone      int8 = 0  
	stepPropose   int8 = 1
	stepPrevote   int8 = 2
	stepPrecommit int8 = 3
)
func voteToStep(vote *types.Vote) int8 {
	switch vote.Type {
	case types.VoteTypePrevote:
		return stepPrevote
	case types.VoteTypePrecommit:
		return stepPrecommit
	default:
		cmn.PanicSanity("Unknown vote type")
		return 0
	}
}
type FilePV struct {
	Address       types.Address    `json:"address"`
	PubKey        crypto.PubKey    `json:"pub_key"`
	LastHeight    int64            `json:"last_height"`
	LastRound     int              `json:"last_round"`
	LastStep      int8             `json:"last_step"`
	LastSignature crypto.Signature `json:"last_signature,omitempty"`  
	LastSignBytes cmn.HexBytes     `json:"last_signbytes,omitempty"`  
	PrivKey       crypto.PrivKey   `json:"priv_key"`
	filePath string
	mtx      sync.Mutex
}
func (pv *FilePV) GetAddress() types.Address {
	return pv.Address
}
func (pv *FilePV) GetPubKey() crypto.PubKey {
	return pv.PubKey
}
func GenFilePV(filePath string) *FilePV {
	privKey := ed25519.GenPrivKey()
	return &FilePV{
		Address:  privKey.PubKey().Address(),
		PubKey:   privKey.PubKey(),
		PrivKey:  privKey,
		LastStep: stepNone,
		filePath: filePath,
	}
}
func LoadFilePV(filePath string) *FilePV {
	pvJSONBytes, err := ioutil.ReadFile(filePath)
	if err != nil {
		cmn.Exit(err.Error())
	}
	pv := &FilePV{}
	err = cdc.UnmarshalJSON(pvJSONBytes, &pv)
	if err != nil {
		cmn.Exit(cmn.Fmt("Error reading PrivValidator from %v: %v\n", filePath, err))
	}
	pv.PubKey = pv.PrivKey.PubKey()
	pv.Address = pv.PubKey.Address()
	pv.filePath = filePath
	return pv
}