mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
split immutable and mutable parts of priv_validator.json
This commit is contained in:
parent
725ed7969a
commit
e8700152be
@ -34,6 +34,7 @@ program](https://hackerone.com/tendermint).
|
||||
reset to 0
|
||||
|
||||
### FEATURES:
|
||||
- [privval] \#1181 Split immutable and mutable parts of priv_validator.json
|
||||
|
||||
### IMPROVEMENTS:
|
||||
|
||||
|
@ -15,7 +15,8 @@ func main() {
|
||||
var (
|
||||
addr = flag.String("addr", ":26659", "Address of client to connect to")
|
||||
chainID = flag.String("chain-id", "mychain", "chain id")
|
||||
privValPath = flag.String("priv", "", "priv val file path")
|
||||
privValKeyPath = flag.String("priv-key", "", "priv val key file path")
|
||||
privValStatePath = flag.String("priv-state", "", "priv val state file path")
|
||||
|
||||
logger = log.NewTMLogger(
|
||||
log.NewSyncWriter(os.Stdout),
|
||||
@ -27,10 +28,11 @@ func main() {
|
||||
"Starting private validator",
|
||||
"addr", *addr,
|
||||
"chainID", *chainID,
|
||||
"privPath", *privValPath,
|
||||
"privKeyPath", *privValKeyPath,
|
||||
"privStatePath", *privValStatePath,
|
||||
)
|
||||
|
||||
pv := privval.LoadFilePV(*privValPath)
|
||||
pv := privval.LoadFilePV(*privValKeyPath, *privValStatePath)
|
||||
|
||||
rs := privval.NewRemoteSigner(
|
||||
logger,
|
||||
|
@ -17,7 +17,7 @@ var GenValidatorCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func genValidator(cmd *cobra.Command, args []string) {
|
||||
pv := privval.GenFilePV("")
|
||||
pv := privval.GenFilePV("", "")
|
||||
jsbz, err := cdc.MarshalJSON(pv)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -26,15 +26,18 @@ func initFiles(cmd *cobra.Command, args []string) error {
|
||||
|
||||
func initFilesWithConfig(config *cfg.Config) error {
|
||||
// private validator
|
||||
privValFile := config.PrivValidatorFile()
|
||||
privValkeyFile := config.PrivValidatorKeyFile()
|
||||
privValStateFile := config.PrivValidatorStateFile()
|
||||
var pv *privval.FilePV
|
||||
if cmn.FileExists(privValFile) {
|
||||
pv = privval.LoadFilePV(privValFile)
|
||||
logger.Info("Found private validator", "path", privValFile)
|
||||
if cmn.FileExists(privValkeyFile) {
|
||||
pv = privval.LoadFilePV(privValkeyFile, privValStateFile)
|
||||
logger.Info("Found private validator", "keyFile", privValkeyFile,
|
||||
"stateFile", privValStateFile)
|
||||
} else {
|
||||
pv = privval.GenFilePV(privValFile)
|
||||
pv = privval.GenFilePV(privValkeyFile, privValStateFile)
|
||||
pv.Save()
|
||||
logger.Info("Generated private validator", "path", privValFile)
|
||||
logger.Info("Generated private validator", "keyFile", privValkeyFile,
|
||||
"stateFile", privValStateFile)
|
||||
}
|
||||
|
||||
nodeKeyFile := config.NodeKeyFile()
|
||||
|
@ -27,19 +27,20 @@ var ResetPrivValidatorCmd = &cobra.Command{
|
||||
// XXX: this is totally unsafe.
|
||||
// it's only suitable for testnets.
|
||||
func resetAll(cmd *cobra.Command, args []string) {
|
||||
ResetAll(config.DBDir(), config.P2P.AddrBookFile(), config.PrivValidatorFile(), logger)
|
||||
ResetAll(config.DBDir(), config.P2P.AddrBookFile(), config.PrivValidatorKeyFile(),
|
||||
config.PrivValidatorStateFile(), logger)
|
||||
}
|
||||
|
||||
// XXX: this is totally unsafe.
|
||||
// it's only suitable for testnets.
|
||||
func resetPrivValidator(cmd *cobra.Command, args []string) {
|
||||
resetFilePV(config.PrivValidatorFile(), logger)
|
||||
resetFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile(), logger)
|
||||
}
|
||||
|
||||
// ResetAll removes the privValidator and address book files plus all data.
|
||||
// Exported so other CLI tools can use it.
|
||||
func ResetAll(dbDir, addrBookFile, privValFile string, logger log.Logger) {
|
||||
resetFilePV(privValFile, logger)
|
||||
func ResetAll(dbDir, addrBookFile, privValKeyFile, privValStateFile string, logger log.Logger) {
|
||||
resetFilePV(privValKeyFile, privValStateFile, logger)
|
||||
removeAddrBook(addrBookFile, logger)
|
||||
if err := os.RemoveAll(dbDir); err == nil {
|
||||
logger.Info("Removed all blockchain history", "dir", dbDir)
|
||||
@ -48,15 +49,17 @@ func ResetAll(dbDir, addrBookFile, privValFile string, logger log.Logger) {
|
||||
}
|
||||
}
|
||||
|
||||
func resetFilePV(privValFile string, logger log.Logger) {
|
||||
if _, err := os.Stat(privValFile); err == nil {
|
||||
pv := privval.LoadFilePV(privValFile)
|
||||
func resetFilePV(privValKeyFile, privValStateFile string, logger log.Logger) {
|
||||
if _, err := os.Stat(privValKeyFile); err == nil {
|
||||
pv := privval.LoadFilePV(privValKeyFile, privValStateFile)
|
||||
pv.Reset()
|
||||
logger.Info("Reset private validator file to genesis state", "file", privValFile)
|
||||
logger.Info("Reset private validator file to genesis state", "keyFile", privValKeyFile,
|
||||
"stateFile", privValStateFile)
|
||||
} else {
|
||||
pv := privval.GenFilePV(privValFile)
|
||||
pv := privval.GenFilePV(privValKeyFile, privValStateFile)
|
||||
pv.Save()
|
||||
logger.Info("Generated private validator file", "file", privValFile)
|
||||
logger.Info("Generated private validator file", "file", "keyFile", privValKeyFile,
|
||||
"stateFile", privValStateFile)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ var ShowValidatorCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func showValidator(cmd *cobra.Command, args []string) {
|
||||
privValidator := privval.LoadOrGenFilePV(config.PrivValidatorFile())
|
||||
privValidator := privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
|
||||
pubKeyJSONBytes, _ := cdc.MarshalJSON(privValidator.GetPubKey())
|
||||
fmt.Println(string(pubKeyJSONBytes))
|
||||
}
|
||||
|
@ -88,8 +88,10 @@ func testnetFiles(cmd *cobra.Command, args []string) error {
|
||||
|
||||
initFilesWithConfig(config)
|
||||
|
||||
pvFile := filepath.Join(nodeDir, config.BaseConfig.PrivValidator)
|
||||
pv := privval.LoadFilePV(pvFile)
|
||||
pvKeyFile := filepath.Join(nodeDir, config.BaseConfig.PrivValidatorKey)
|
||||
pvStateFile := filepath.Join(nodeDir, config.BaseConfig.PrivValidatorState)
|
||||
|
||||
pv := privval.LoadFilePV(pvKeyFile, pvStateFile)
|
||||
genVals[i] = types.GenesisValidator{
|
||||
Address: pv.GetPubKey().Address(),
|
||||
PubKey: pv.GetPubKey(),
|
||||
|
@ -35,13 +35,17 @@ var (
|
||||
defaultConfigFileName = "config.toml"
|
||||
defaultGenesisJSONName = "genesis.json"
|
||||
|
||||
defaultPrivValName = "priv_validator.json"
|
||||
defaultPrivValKeyName = "priv_validator_key.json"
|
||||
defaultPrivValStateName = "priv_validator_state.json"
|
||||
|
||||
defaultNodeKeyName = "node_key.json"
|
||||
defaultAddrBookName = "addrbook.json"
|
||||
|
||||
defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName)
|
||||
defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName)
|
||||
defaultPrivValPath = filepath.Join(defaultConfigDir, defaultPrivValName)
|
||||
defaultPrivValKeyPath = filepath.Join(defaultConfigDir, defaultPrivValKeyName)
|
||||
defaultPrivValStatePath = filepath.Join(defaultDataDir, defaultPrivValStateName)
|
||||
|
||||
defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName)
|
||||
defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName)
|
||||
)
|
||||
@ -160,7 +164,10 @@ type BaseConfig struct {
|
||||
Genesis string `mapstructure:"genesis_file"`
|
||||
|
||||
// Path to the JSON file containing the private key to use as a validator in the consensus protocol
|
||||
PrivValidator string `mapstructure:"priv_validator_file"`
|
||||
PrivValidatorKey string `mapstructure:"priv_validator_key_file"`
|
||||
|
||||
// Path to the JSON file containing the last sign state of a validator
|
||||
PrivValidatorState string `mapstructure:"priv_validator_state_file"`
|
||||
|
||||
// TCP or UNIX socket address for Tendermint to listen on for
|
||||
// connections from an external PrivValidator process
|
||||
@ -184,7 +191,8 @@ type BaseConfig struct {
|
||||
func DefaultBaseConfig() BaseConfig {
|
||||
return BaseConfig{
|
||||
Genesis: defaultGenesisJSONPath,
|
||||
PrivValidator: defaultPrivValPath,
|
||||
PrivValidatorKey: defaultPrivValKeyPath,
|
||||
PrivValidatorState: defaultPrivValStatePath,
|
||||
NodeKey: defaultNodeKeyPath,
|
||||
Moniker: defaultMoniker,
|
||||
ProxyApp: "tcp://127.0.0.1:26658",
|
||||
@ -218,9 +226,14 @@ func (cfg BaseConfig) GenesisFile() string {
|
||||
return rootify(cfg.Genesis, cfg.RootDir)
|
||||
}
|
||||
|
||||
// PrivValidatorFile returns the full path to the priv_validator.json file
|
||||
func (cfg BaseConfig) PrivValidatorFile() string {
|
||||
return rootify(cfg.PrivValidator, cfg.RootDir)
|
||||
// PrivValidatorKeyFile returns the full path to the priv_validator_key.json file
|
||||
func (cfg BaseConfig) PrivValidatorKeyFile() string {
|
||||
return rootify(cfg.PrivValidatorKey, cfg.RootDir)
|
||||
}
|
||||
|
||||
// PrivValidatorFile returns the full path to the priv_validator_state.json file
|
||||
func (cfg BaseConfig) PrivValidatorStateFile() string {
|
||||
return rootify(cfg.PrivValidatorState, cfg.RootDir)
|
||||
}
|
||||
|
||||
// NodeKeyFile returns the full path to the node_key.json file
|
||||
|
@ -95,7 +95,10 @@ log_format = "{{ .BaseConfig.LogFormat }}"
|
||||
genesis_file = "{{ js .BaseConfig.Genesis }}"
|
||||
|
||||
# Path to the JSON file containing the private key to use as a validator in the consensus protocol
|
||||
priv_validator_file = "{{ js .BaseConfig.PrivValidator }}"
|
||||
priv_validator_key_file = "{{ js .BaseConfig.PrivValidatorKey }}"
|
||||
|
||||
# Path to the JSON file containing the last sign state of a validator
|
||||
priv_validator_state_file = "{{ js .BaseConfig.PrivValidatorState }}"
|
||||
|
||||
# TCP or UNIX socket address for Tendermint to listen on for
|
||||
# connections from an external PrivValidator process
|
||||
@ -342,7 +345,8 @@ func ResetTestRoot(testName string) *Config {
|
||||
baseConfig := DefaultBaseConfig()
|
||||
configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
|
||||
genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis)
|
||||
privFilePath := filepath.Join(rootDir, baseConfig.PrivValidator)
|
||||
privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey)
|
||||
privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState)
|
||||
|
||||
// Write default config file if missing.
|
||||
if !cmn.FileExists(configFilePath) {
|
||||
@ -352,7 +356,8 @@ func ResetTestRoot(testName string) *Config {
|
||||
cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)
|
||||
}
|
||||
// we always overwrite the priv val
|
||||
cmn.MustWriteFile(privFilePath, []byte(testPrivValidator), 0644)
|
||||
cmn.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0644)
|
||||
cmn.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0644)
|
||||
|
||||
config := TestConfig().SetRoot(rootDir)
|
||||
return config
|
||||
@ -374,7 +379,7 @@ var testGenesis = `{
|
||||
"app_hash": ""
|
||||
}`
|
||||
|
||||
var testPrivValidator = `{
|
||||
var testPrivValidatorKey = `{
|
||||
"address": "A3258DCBF45DCA0DF052981870F2D1441A36D145",
|
||||
"pub_key": {
|
||||
"type": "tendermint/PubKeyEd25519",
|
||||
@ -383,8 +388,11 @@ var testPrivValidator = `{
|
||||
"priv_key": {
|
||||
"type": "tendermint/PrivKeyEd25519",
|
||||
"value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ=="
|
||||
},
|
||||
"last_height": "0",
|
||||
"last_round": "0",
|
||||
"last_step": 0
|
||||
}
|
||||
}`
|
||||
|
||||
var testPrivValidatorState = `{
|
||||
"height": "0",
|
||||
"round": "0",
|
||||
"step": 0
|
||||
}`
|
||||
|
@ -60,7 +60,7 @@ func TestEnsureTestRoot(t *testing.T) {
|
||||
|
||||
// TODO: make sure the cfg returned and testconfig are the same!
|
||||
baseConfig := DefaultBaseConfig()
|
||||
ensureFiles(t, rootDir, defaultDataDir, baseConfig.Genesis, baseConfig.PrivValidator)
|
||||
ensureFiles(t, rootDir, defaultDataDir, baseConfig.Genesis, baseConfig.PrivValidatorKey, baseConfig.PrivValidatorState)
|
||||
}
|
||||
|
||||
func checkConfig(configFile string) bool {
|
||||
|
@ -281,9 +281,10 @@ func newConsensusStateWithConfigAndBlockStore(thisConfig *cfg.Config, state sm.S
|
||||
}
|
||||
|
||||
func loadPrivValidator(config *cfg.Config) *privval.FilePV {
|
||||
privValidatorFile := config.PrivValidatorFile()
|
||||
ensureDir(path.Dir(privValidatorFile), 0700)
|
||||
privValidator := privval.LoadOrGenFilePV(privValidatorFile)
|
||||
privValidatorKeyFile := config.PrivValidatorKeyFile()
|
||||
ensureDir(path.Dir(privValidatorKeyFile), 0700)
|
||||
privValidatorStateFile := config.PrivValidatorStateFile()
|
||||
privValidator := privval.LoadOrGenFilePV(privValidatorKeyFile, privValidatorStateFile)
|
||||
privValidator.Reset()
|
||||
return privValidator
|
||||
}
|
||||
@ -617,11 +618,16 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF
|
||||
if i < nValidators {
|
||||
privVal = privVals[i]
|
||||
} else {
|
||||
tempFile, err := ioutil.TempFile("", "priv_validator_")
|
||||
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
privVal = privval.GenFilePV(tempFile.Name())
|
||||
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
privVal = privval.GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
|
||||
}
|
||||
|
||||
app := appFunc()
|
||||
|
@ -319,7 +319,7 @@ func testHandshakeReplay(t *testing.T, nBlocks int, mode uint) {
|
||||
walFile := tempWALWithData(walBody)
|
||||
config.Consensus.SetWalFile(walFile)
|
||||
|
||||
privVal := privval.LoadFilePV(config.PrivValidatorFile())
|
||||
privVal := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
|
||||
|
||||
wal, err := NewWAL(walFile)
|
||||
require.NoError(t, err)
|
||||
@ -633,7 +633,7 @@ func TestInitChainUpdateValidators(t *testing.T) {
|
||||
clientCreator := proxy.NewLocalClientCreator(app)
|
||||
|
||||
config := ResetConfig("proxy_test_")
|
||||
privVal := privval.LoadFilePV(config.PrivValidatorFile())
|
||||
privVal := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
|
||||
stateDB, state, store := stateAndStore(config, privVal.GetPubKey(), 0x0)
|
||||
|
||||
oldValAddr := state.Validators.Validators[0].Address
|
||||
|
@ -40,8 +40,9 @@ func WALGenerateNBlocks(wr io.Writer, numBlocks int) (err error) {
|
||||
// COPY PASTE FROM node.go WITH A FEW MODIFICATIONS
|
||||
// NOTE: we can't import node package because of circular dependency.
|
||||
// NOTE: we don't do handshake so need to set state.Version.Consensus.App directly.
|
||||
privValidatorFile := config.PrivValidatorFile()
|
||||
privValidator := privval.LoadOrGenFilePV(privValidatorFile)
|
||||
privValidatorKeyFile := config.PrivValidatorKeyFile()
|
||||
privValidatorStateFile := config.PrivValidatorStateFile()
|
||||
privValidator := privval.LoadOrGenFilePV(privValidatorKeyFile, privValidatorStateFile)
|
||||
genDoc, err := types.GenesisDocFromFile(config.GenesisFile())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read genesis file")
|
||||
|
@ -87,7 +87,7 @@ func DefaultNewNode(config *cfg.Config, logger log.Logger) (*Node, error) {
|
||||
return nil, err
|
||||
}
|
||||
return NewNode(config,
|
||||
privval.LoadOrGenFilePV(config.PrivValidatorFile()),
|
||||
privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()),
|
||||
nodeKey,
|
||||
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()),
|
||||
DefaultGenesisDocProviderFunc(config),
|
||||
|
@ -37,21 +37,31 @@ func voteToStep(vote *types.Vote) int8 {
|
||||
|
||||
// FilePV implements PrivValidator using data persisted to disk
|
||||
// to prevent double signing.
|
||||
// NOTE: the directory containing the pv.filePath must already exist.
|
||||
// NOTE: the directories containing pv.Key.filePath and pv.LastSignState.filePath must already exist.
|
||||
// It includes the LastSignature and LastSignBytes so we don't lose the signature
|
||||
// if the process crashes after signing but before the resulting consensus message is processed.
|
||||
type FilePV struct {
|
||||
Key FilePVKey
|
||||
LastSignState FilePVLastSignState
|
||||
}
|
||||
|
||||
// FilePVKey stores the immutable part of PrivValidator
|
||||
type FilePVKey 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 []byte `json:"last_signature,omitempty"`
|
||||
LastSignBytes cmn.HexBytes `json:"last_signbytes,omitempty"`
|
||||
PrivKey crypto.PrivKey `json:"priv_key"`
|
||||
|
||||
// For persistence.
|
||||
// Overloaded for testing.
|
||||
filePath string
|
||||
}
|
||||
|
||||
// FilePVState stores the mutable part of PrivValidator
|
||||
type FilePVLastSignState struct {
|
||||
Height int64 `json:"height"`
|
||||
Round int `json:"round"`
|
||||
Step int8 `json:"step"`
|
||||
Signature []byte `json:"signature,omitempty"`
|
||||
SignBytes cmn.HexBytes `json:"signbytes,omitempty"`
|
||||
|
||||
filePath string
|
||||
mtx sync.Mutex
|
||||
}
|
||||
@ -59,58 +69,82 @@ type FilePV struct {
|
||||
// GetAddress returns the address of the validator.
|
||||
// Implements PrivValidator.
|
||||
func (pv *FilePV) GetAddress() types.Address {
|
||||
return pv.Address
|
||||
return pv.Key.Address
|
||||
}
|
||||
|
||||
// GetPubKey returns the public key of the validator.
|
||||
// Implements PrivValidator.
|
||||
func (pv *FilePV) GetPubKey() crypto.PubKey {
|
||||
return pv.PubKey
|
||||
return pv.Key.PubKey
|
||||
}
|
||||
|
||||
// GenFilePV generates a new validator with randomly generated private key
|
||||
// and sets the filePath, but does not call Save().
|
||||
func GenFilePV(filePath string) *FilePV {
|
||||
// and sets the filePaths, but does not call Save().
|
||||
func GenFilePV(keyFilePath string, stateFilePath string) *FilePV {
|
||||
privKey := ed25519.GenPrivKey()
|
||||
|
||||
return &FilePV{
|
||||
Key: FilePVKey{
|
||||
Address: privKey.PubKey().Address(),
|
||||
PubKey: privKey.PubKey(),
|
||||
PrivKey: privKey,
|
||||
LastStep: stepNone,
|
||||
filePath: filePath,
|
||||
filePath: keyFilePath,
|
||||
},
|
||||
LastSignState: FilePVLastSignState{
|
||||
Step: stepNone,
|
||||
filePath: stateFilePath,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// LoadFilePV loads a FilePV from the filePath. The FilePV handles double
|
||||
// signing prevention by persisting data to the filePath. If the filePath does
|
||||
// LoadFilePV loads a FilePV from the filePaths. The FilePV handles double
|
||||
// signing prevention by persisting data to the stateFilePath. If the filePaths does
|
||||
// not exist, the FilePV must be created manually and saved.
|
||||
func LoadFilePV(filePath string) *FilePV {
|
||||
pvJSONBytes, err := ioutil.ReadFile(filePath)
|
||||
func LoadFilePV(keyFilePath string, stateFilePath string) *FilePV {
|
||||
keyJSONBytes, err := ioutil.ReadFile(keyFilePath)
|
||||
if err != nil {
|
||||
cmn.Exit(err.Error())
|
||||
}
|
||||
pv := &FilePV{}
|
||||
err = cdc.UnmarshalJSON(pvJSONBytes, &pv)
|
||||
pvKey := FilePVKey{}
|
||||
err = cdc.UnmarshalJSON(keyJSONBytes, &pvKey)
|
||||
if err != nil {
|
||||
cmn.Exit(fmt.Sprintf("Error reading PrivValidator from %v: %v\n", filePath, err))
|
||||
cmn.Exit(fmt.Sprintf("Error reading PrivValidator key from %v: %v\n", keyFilePath, err))
|
||||
}
|
||||
|
||||
// overwrite pubkey and address for convenience
|
||||
pv.PubKey = pv.PrivKey.PubKey()
|
||||
pv.Address = pv.PubKey.Address()
|
||||
pvKey.PubKey = pvKey.PrivKey.PubKey()
|
||||
pvKey.Address = pvKey.PubKey.Address()
|
||||
pvKey.filePath = keyFilePath
|
||||
|
||||
stateJSONBytes, err := ioutil.ReadFile(stateFilePath)
|
||||
if err != nil {
|
||||
cmn.Exit(err.Error())
|
||||
}
|
||||
pvState := FilePVLastSignState{}
|
||||
err = cdc.UnmarshalJSON(stateJSONBytes, &pvState)
|
||||
if err != nil {
|
||||
cmn.Exit(fmt.Sprintf("Error reading PrivValidator state from %v: %v\n", stateFilePath, err))
|
||||
}
|
||||
|
||||
pvState.filePath = stateFilePath
|
||||
|
||||
pv := &FilePV{}
|
||||
|
||||
pv.Key = pvKey
|
||||
pv.LastSignState = pvState
|
||||
|
||||
pv.filePath = filePath
|
||||
return pv
|
||||
}
|
||||
|
||||
// LoadOrGenFilePV loads a FilePV from the given filePath
|
||||
// or else generates a new one and saves it to the filePath.
|
||||
func LoadOrGenFilePV(filePath string) *FilePV {
|
||||
// LoadOrGenFilePV loads a FilePV from the given filePaths
|
||||
// or else generates a new one and saves it to the filePaths.
|
||||
func LoadOrGenFilePV(keyFilePath string, stateFilePath string) *FilePV {
|
||||
var pv *FilePV
|
||||
if cmn.FileExists(filePath) {
|
||||
pv = LoadFilePV(filePath)
|
||||
if cmn.FileExists(keyFilePath) {
|
||||
println(keyFilePath)
|
||||
pv = LoadFilePV(keyFilePath, stateFilePath)
|
||||
} else {
|
||||
pv = GenFilePV(filePath)
|
||||
pv = GenFilePV(keyFilePath, stateFilePath)
|
||||
pv.Save()
|
||||
}
|
||||
return pv
|
||||
@ -118,17 +152,36 @@ func LoadOrGenFilePV(filePath string) *FilePV {
|
||||
|
||||
// Save persists the FilePV to disk.
|
||||
func (pv *FilePV) Save() {
|
||||
pv.mtx.Lock()
|
||||
defer pv.mtx.Unlock()
|
||||
pv.save()
|
||||
pv.saveKey()
|
||||
|
||||
pv.LastSignState.mtx.Lock()
|
||||
defer pv.LastSignState.mtx.Unlock()
|
||||
pv.saveState()
|
||||
}
|
||||
|
||||
func (pv *FilePV) save() {
|
||||
outFile := pv.filePath
|
||||
func (pv *FilePV) saveKey() {
|
||||
outFile := pv.Key.filePath
|
||||
if outFile == "" {
|
||||
panic("Cannot save PrivValidator: filePath not set")
|
||||
panic("Cannot save PrivValidator key: filePath not set")
|
||||
}
|
||||
jsonBytes, err := cdc.MarshalJSONIndent(pv, "", " ")
|
||||
|
||||
jsonBytes, err := cdc.MarshalJSONIndent(pv.Key, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = cmn.WriteFileAtomic(outFile, jsonBytes, 0600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (pv *FilePV) saveState() {
|
||||
outFile := pv.LastSignState.filePath
|
||||
if outFile == "" {
|
||||
panic("Cannot save PrivValidator state: filePath not set")
|
||||
}
|
||||
jsonBytes, err := cdc.MarshalJSONIndent(pv.LastSignState, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -142,19 +195,19 @@ func (pv *FilePV) save() {
|
||||
// NOTE: Unsafe!
|
||||
func (pv *FilePV) Reset() {
|
||||
var sig []byte
|
||||
pv.LastHeight = 0
|
||||
pv.LastRound = 0
|
||||
pv.LastStep = 0
|
||||
pv.LastSignature = sig
|
||||
pv.LastSignBytes = nil
|
||||
pv.LastSignState.Height = 0
|
||||
pv.LastSignState.Round = 0
|
||||
pv.LastSignState.Step = 0
|
||||
pv.LastSignState.Signature = sig
|
||||
pv.LastSignState.SignBytes = nil
|
||||
pv.Save()
|
||||
}
|
||||
|
||||
// SignVote signs a canonical representation of the vote, along with the
|
||||
// chainID. Implements PrivValidator.
|
||||
func (pv *FilePV) SignVote(chainID string, vote *types.Vote) error {
|
||||
pv.mtx.Lock()
|
||||
defer pv.mtx.Unlock()
|
||||
pv.LastSignState.mtx.Lock()
|
||||
defer pv.LastSignState.mtx.Unlock()
|
||||
if err := pv.signVote(chainID, vote); err != nil {
|
||||
return fmt.Errorf("Error signing vote: %v", err)
|
||||
}
|
||||
@ -164,8 +217,8 @@ func (pv *FilePV) SignVote(chainID string, vote *types.Vote) error {
|
||||
// SignProposal signs a canonical representation of the proposal, along with
|
||||
// the chainID. Implements PrivValidator.
|
||||
func (pv *FilePV) SignProposal(chainID string, proposal *types.Proposal) error {
|
||||
pv.mtx.Lock()
|
||||
defer pv.mtx.Unlock()
|
||||
pv.LastSignState.mtx.Lock()
|
||||
defer pv.LastSignState.mtx.Unlock()
|
||||
if err := pv.signProposal(chainID, proposal); err != nil {
|
||||
return fmt.Errorf("Error signing proposal: %v", err)
|
||||
}
|
||||
@ -174,21 +227,21 @@ func (pv *FilePV) SignProposal(chainID string, proposal *types.Proposal) error {
|
||||
|
||||
// returns error if HRS regression or no LastSignBytes. returns true if HRS is unchanged
|
||||
func (pv *FilePV) checkHRS(height int64, round int, step int8) (bool, error) {
|
||||
if pv.LastHeight > height {
|
||||
if pv.LastSignState.Height > height {
|
||||
return false, errors.New("Height regression")
|
||||
}
|
||||
|
||||
if pv.LastHeight == height {
|
||||
if pv.LastRound > round {
|
||||
if pv.LastSignState.Height == height {
|
||||
if pv.LastSignState.Round > round {
|
||||
return false, errors.New("Round regression")
|
||||
}
|
||||
|
||||
if pv.LastRound == round {
|
||||
if pv.LastStep > step {
|
||||
if pv.LastSignState.Round == round {
|
||||
if pv.LastSignState.Step > step {
|
||||
return false, errors.New("Step regression")
|
||||
} else if pv.LastStep == step {
|
||||
if pv.LastSignBytes != nil {
|
||||
if pv.LastSignature == nil {
|
||||
} else if pv.LastSignState.Step == step {
|
||||
if pv.LastSignState.SignBytes != nil {
|
||||
if pv.LastSignState.Signature == nil {
|
||||
panic("pv: LastSignature is nil but LastSignBytes is not!")
|
||||
}
|
||||
return true, nil
|
||||
@ -218,11 +271,11 @@ func (pv *FilePV) signVote(chainID string, vote *types.Vote) error {
|
||||
// If they only differ by timestamp, use last timestamp and signature
|
||||
// Otherwise, return error
|
||||
if sameHRS {
|
||||
if bytes.Equal(signBytes, pv.LastSignBytes) {
|
||||
vote.Signature = pv.LastSignature
|
||||
} else if timestamp, ok := checkVotesOnlyDifferByTimestamp(pv.LastSignBytes, signBytes); ok {
|
||||
if bytes.Equal(signBytes, pv.LastSignState.SignBytes) {
|
||||
vote.Signature = pv.LastSignState.Signature
|
||||
} else if timestamp, ok := checkVotesOnlyDifferByTimestamp(pv.LastSignState.SignBytes, signBytes); ok {
|
||||
vote.Timestamp = timestamp
|
||||
vote.Signature = pv.LastSignature
|
||||
vote.Signature = pv.LastSignState.Signature
|
||||
} else {
|
||||
err = fmt.Errorf("Conflicting data")
|
||||
}
|
||||
@ -230,7 +283,7 @@ func (pv *FilePV) signVote(chainID string, vote *types.Vote) error {
|
||||
}
|
||||
|
||||
// It passed the checks. Sign the vote
|
||||
sig, err := pv.PrivKey.Sign(signBytes)
|
||||
sig, err := pv.Key.PrivKey.Sign(signBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -257,11 +310,11 @@ func (pv *FilePV) signProposal(chainID string, proposal *types.Proposal) error {
|
||||
// If they only differ by timestamp, use last timestamp and signature
|
||||
// Otherwise, return error
|
||||
if sameHRS {
|
||||
if bytes.Equal(signBytes, pv.LastSignBytes) {
|
||||
proposal.Signature = pv.LastSignature
|
||||
} else if timestamp, ok := checkProposalsOnlyDifferByTimestamp(pv.LastSignBytes, signBytes); ok {
|
||||
if bytes.Equal(signBytes, pv.LastSignState.SignBytes) {
|
||||
proposal.Signature = pv.LastSignState.Signature
|
||||
} else if timestamp, ok := checkProposalsOnlyDifferByTimestamp(pv.LastSignState.SignBytes, signBytes); ok {
|
||||
proposal.Timestamp = timestamp
|
||||
proposal.Signature = pv.LastSignature
|
||||
proposal.Signature = pv.LastSignState.Signature
|
||||
} else {
|
||||
err = fmt.Errorf("Conflicting data")
|
||||
}
|
||||
@ -269,7 +322,7 @@ func (pv *FilePV) signProposal(chainID string, proposal *types.Proposal) error {
|
||||
}
|
||||
|
||||
// It passed the checks. Sign the proposal
|
||||
sig, err := pv.PrivKey.Sign(signBytes)
|
||||
sig, err := pv.Key.PrivKey.Sign(signBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -282,17 +335,17 @@ func (pv *FilePV) signProposal(chainID string, proposal *types.Proposal) error {
|
||||
func (pv *FilePV) saveSigned(height int64, round int, step int8,
|
||||
signBytes []byte, sig []byte) {
|
||||
|
||||
pv.LastHeight = height
|
||||
pv.LastRound = round
|
||||
pv.LastStep = step
|
||||
pv.LastSignature = sig
|
||||
pv.LastSignBytes = signBytes
|
||||
pv.save()
|
||||
pv.LastSignState.Height = height
|
||||
pv.LastSignState.Round = round
|
||||
pv.LastSignState.Step = step
|
||||
pv.LastSignState.Signature = sig
|
||||
pv.LastSignState.SignBytes = signBytes
|
||||
pv.saveState()
|
||||
}
|
||||
|
||||
// String returns a string representation of the FilePV.
|
||||
func (pv *FilePV) String() string {
|
||||
return fmt.Sprintf("PrivValidator{%v LH:%v, LR:%v, LS:%v}", pv.GetAddress(), pv.LastHeight, pv.LastRound, pv.LastStep)
|
||||
return fmt.Sprintf("PrivValidator{%v LH:%v, LR:%v, LS:%v}", pv.GetAddress(), pv.LastSignState.Height, pv.LastSignState.Round, pv.LastSignState.Step)
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -18,36 +18,72 @@ import (
|
||||
func TestGenLoadValidator(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tempFile, err := ioutil.TempFile("", "priv_validator_")
|
||||
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
|
||||
require.Nil(t, err)
|
||||
privVal := GenFilePV(tempFile.Name())
|
||||
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
|
||||
require.Nil(t, err)
|
||||
|
||||
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
|
||||
|
||||
height := int64(100)
|
||||
privVal.LastHeight = height
|
||||
privVal.LastSignState.Height = height
|
||||
privVal.Save()
|
||||
addr := privVal.GetAddress()
|
||||
|
||||
privVal = LoadFilePV(tempFile.Name())
|
||||
privVal = LoadFilePV(tempKeyFile.Name(), tempStateFile.Name())
|
||||
assert.Equal(addr, privVal.GetAddress(), "expected privval addr to be the same")
|
||||
assert.Equal(height, privVal.LastHeight, "expected privval.LastHeight to have been saved")
|
||||
assert.Equal(height, privVal.LastSignState.Height, "expected privval.LastHeight to have been saved")
|
||||
}
|
||||
|
||||
func TestLoadOrGenValidator(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tempFile, err := ioutil.TempFile("", "priv_validator_")
|
||||
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
|
||||
require.Nil(t, err)
|
||||
tempFilePath := tempFile.Name()
|
||||
if err := os.Remove(tempFilePath); err != nil {
|
||||
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
|
||||
require.Nil(t, err)
|
||||
|
||||
tempKeyFilePath := tempKeyFile.Name()
|
||||
if err := os.Remove(tempKeyFilePath); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
privVal := LoadOrGenFilePV(tempFilePath)
|
||||
tempStateFilePath := tempStateFile.Name()
|
||||
if err := os.Remove(tempStateFilePath); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
privVal := LoadOrGenFilePV(tempKeyFilePath, tempStateFilePath)
|
||||
addr := privVal.GetAddress()
|
||||
privVal = LoadOrGenFilePV(tempFilePath)
|
||||
privVal = LoadOrGenFilePV(tempKeyFilePath, tempStateFilePath)
|
||||
assert.Equal(addr, privVal.GetAddress(), "expected privval addr to be the same")
|
||||
}
|
||||
|
||||
func TestUnmarshalValidator(t *testing.T) {
|
||||
func TestUnmarshalValidatorState(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
// create some fixed values
|
||||
serialized := fmt.Sprintf(`{
|
||||
"height": "1",
|
||||
"round": "1",
|
||||
"step": 1
|
||||
}`)
|
||||
|
||||
val := FilePVLastSignState{}
|
||||
err := cdc.UnmarshalJSON([]byte(serialized), &val)
|
||||
require.Nil(err, "%+v", err)
|
||||
|
||||
// make sure the values match
|
||||
assert.EqualValues(val.Height, 1)
|
||||
assert.EqualValues(val.Round, 1)
|
||||
assert.EqualValues(val.Step, 1)
|
||||
|
||||
// export it and make sure it is the same
|
||||
out, err := cdc.MarshalJSON(val)
|
||||
require.Nil(err, "%+v", err)
|
||||
assert.JSONEq(serialized, string(out))
|
||||
}
|
||||
|
||||
func TestUnmarshalValidatorKey(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
// create some fixed values
|
||||
@ -67,22 +103,19 @@ func TestUnmarshalValidator(t *testing.T) {
|
||||
"type": "tendermint/PubKeyEd25519",
|
||||
"value": "%s"
|
||||
},
|
||||
"last_height": "0",
|
||||
"last_round": "0",
|
||||
"last_step": 0,
|
||||
"priv_key": {
|
||||
"type": "tendermint/PrivKeyEd25519",
|
||||
"value": "%s"
|
||||
}
|
||||
}`, addr, pubB64, privB64)
|
||||
|
||||
val := FilePV{}
|
||||
val := FilePVKey{}
|
||||
err := cdc.UnmarshalJSON([]byte(serialized), &val)
|
||||
require.Nil(err, "%+v", err)
|
||||
|
||||
// make sure the values match
|
||||
assert.EqualValues(addr, val.GetAddress())
|
||||
assert.EqualValues(pubKey, val.GetPubKey())
|
||||
assert.EqualValues(addr, val.Address)
|
||||
assert.EqualValues(pubKey, val.PubKey)
|
||||
assert.EqualValues(privKey, val.PrivKey)
|
||||
|
||||
// export it and make sure it is the same
|
||||
@ -94,9 +127,12 @@ func TestUnmarshalValidator(t *testing.T) {
|
||||
func TestSignVote(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tempFile, err := ioutil.TempFile("", "priv_validator_")
|
||||
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
|
||||
require.Nil(t, err)
|
||||
privVal := GenFilePV(tempFile.Name())
|
||||
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
|
||||
require.Nil(t, err)
|
||||
|
||||
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
|
||||
|
||||
block1 := types.BlockID{[]byte{1, 2, 3}, types.PartSetHeader{}}
|
||||
block2 := types.BlockID{[]byte{3, 2, 1}, types.PartSetHeader{}}
|
||||
@ -104,7 +140,7 @@ func TestSignVote(t *testing.T) {
|
||||
voteType := byte(types.PrevoteType)
|
||||
|
||||
// sign a vote for first time
|
||||
vote := newVote(privVal.Address, 0, height, round, voteType, block1)
|
||||
vote := newVote(privVal.Key.Address, 0, height, round, voteType, block1)
|
||||
err = privVal.SignVote("mychainid", vote)
|
||||
assert.NoError(err, "expected no error signing vote")
|
||||
|
||||
@ -114,10 +150,10 @@ func TestSignVote(t *testing.T) {
|
||||
|
||||
// now try some bad votes
|
||||
cases := []*types.Vote{
|
||||
newVote(privVal.Address, 0, height, round-1, voteType, block1), // round regression
|
||||
newVote(privVal.Address, 0, height-1, round, voteType, block1), // height regression
|
||||
newVote(privVal.Address, 0, height-2, round+4, voteType, block1), // height regression and different round
|
||||
newVote(privVal.Address, 0, height, round, voteType, block2), // different block
|
||||
newVote(privVal.Key.Address, 0, height, round-1, voteType, block1), // round regression
|
||||
newVote(privVal.Key.Address, 0, height-1, round, voteType, block1), // height regression
|
||||
newVote(privVal.Key.Address, 0, height-2, round+4, voteType, block1), // height regression and different round
|
||||
newVote(privVal.Key.Address, 0, height, round, voteType, block2), // different block
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@ -136,9 +172,12 @@ func TestSignVote(t *testing.T) {
|
||||
func TestSignProposal(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tempFile, err := ioutil.TempFile("", "priv_validator_")
|
||||
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
|
||||
require.Nil(t, err)
|
||||
privVal := GenFilePV(tempFile.Name())
|
||||
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
|
||||
require.Nil(t, err)
|
||||
|
||||
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
|
||||
|
||||
block1 := types.BlockID{[]byte{1, 2, 3}, types.PartSetHeader{5, []byte{1, 2, 3}}}
|
||||
block2 := types.BlockID{[]byte{3, 2, 1}, types.PartSetHeader{10, []byte{3, 2, 1}}}
|
||||
@ -175,9 +214,12 @@ func TestSignProposal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDifferByTimestamp(t *testing.T) {
|
||||
tempFile, err := ioutil.TempFile("", "priv_validator_")
|
||||
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
|
||||
require.Nil(t, err)
|
||||
privVal := GenFilePV(tempFile.Name())
|
||||
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
|
||||
require.Nil(t, err)
|
||||
|
||||
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
|
||||
|
||||
block1 := types.BlockID{[]byte{1, 2, 3}, types.PartSetHeader{5, []byte{1, 2, 3}}}
|
||||
height, round := int64(10), 1
|
||||
@ -208,7 +250,7 @@ func TestDifferByTimestamp(t *testing.T) {
|
||||
{
|
||||
voteType := byte(types.PrevoteType)
|
||||
blockID := types.BlockID{[]byte{1, 2, 3}, types.PartSetHeader{}}
|
||||
vote := newVote(privVal.Address, 0, height, round, voteType, blockID)
|
||||
vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID)
|
||||
err := privVal.SignVote("mychainid", vote)
|
||||
assert.NoError(t, err, "expected no error signing vote")
|
||||
|
||||
|
@ -119,8 +119,9 @@ func NewTendermint(app abci.Application) *nm.Node {
|
||||
config := GetConfig()
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||
logger = log.NewFilter(logger, log.AllowError())
|
||||
pvFile := config.PrivValidatorFile()
|
||||
pv := privval.LoadOrGenFilePV(pvFile)
|
||||
pvKeyFile := config.PrivValidatorKeyFile()
|
||||
pvKeyStateFile := config.PrivValidatorStateFile()
|
||||
pv := privval.LoadOrGenFilePV(pvKeyFile, pvKeyStateFile)
|
||||
papp := proxy.NewLocalClientCreator(app)
|
||||
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
|
||||
if err != nil {
|
||||
|
@ -48,6 +48,18 @@ type PrivVal struct {
|
||||
PrivKey Data `json:"priv_key"`
|
||||
}
|
||||
|
||||
type PrivValKey struct {
|
||||
Address cmn.HexBytes `json:"address"`
|
||||
PubKey Data `json:"pub_key"`
|
||||
PrivKey Data `json:"priv_key"`
|
||||
}
|
||||
|
||||
type PrivValState struct {
|
||||
LastHeight int64 `json:"last_height"`
|
||||
LastRound int `json:"last_round"`
|
||||
LastStep int8 `json:"last_step"`
|
||||
}
|
||||
|
||||
type Data struct {
|
||||
Type string `json:"type"`
|
||||
Data cmn.HexBytes `json:"data"`
|
||||
@ -72,8 +84,8 @@ func convertNodeKey(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func convertPrivVal(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
|
||||
var privVal PrivVal
|
||||
func convertPrivValKey(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
|
||||
var privVal PrivValKey
|
||||
err := json.Unmarshal(jsonBytes, &privVal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -85,12 +97,9 @@ func convertPrivVal(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
|
||||
var pubKey ed25519.PubKeyEd25519
|
||||
copy(pubKey[:], privVal.PubKey.Data)
|
||||
|
||||
privValNew := privval.FilePV{
|
||||
privValNew := privval.FilePVKey{
|
||||
Address: pubKey.Address(),
|
||||
PubKey: pubKey,
|
||||
LastHeight: privVal.LastHeight,
|
||||
LastRound: privVal.LastRound,
|
||||
LastStep: privVal.LastStep,
|
||||
PrivKey: privKey,
|
||||
}
|
||||
|
||||
@ -101,6 +110,26 @@ func convertPrivVal(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func convertPrivValState(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
|
||||
var privVal PrivValState
|
||||
err := json.Unmarshal(jsonBytes, &privVal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
privValNew := privval.FilePVLastSignState{
|
||||
Height: privVal.LastHeight,
|
||||
Round: privVal.LastRound,
|
||||
Step: privVal.LastStep,
|
||||
}
|
||||
|
||||
bz, err := cdc.MarshalJSON(privValNew)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func convertGenesis(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
|
||||
var genesis Genesis
|
||||
err := json.Unmarshal(jsonBytes, &genesis)
|
||||
@ -165,8 +194,10 @@ func main() {
|
||||
switch fileName {
|
||||
case "node_key.json":
|
||||
bz, err = convertNodeKey(cdc, fileBytes)
|
||||
case "priv_validator.json":
|
||||
bz, err = convertPrivVal(cdc, fileBytes)
|
||||
case "priv_validator_key.json":
|
||||
bz, err = convertPrivValKey(cdc, fileBytes)
|
||||
case "priv_validator_state.json":
|
||||
bz, err = convertPrivValState(cdc, fileBytes)
|
||||
case "genesis.json":
|
||||
bz, err = convertGenesis(cdc, fileBytes)
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user