The old format was deprecated in v0.28. It's time we remove it.pull/4757/head
@ -1,81 +0,0 @@ | |||
package privval | |||
import ( | |||
"io/ioutil" | |||
"os" | |||
"github.com/tendermint/tendermint/crypto" | |||
"github.com/tendermint/tendermint/libs/bytes" | |||
"github.com/tendermint/tendermint/types" | |||
) | |||
// OldFilePV is the old version of the FilePV, pre v0.28.0. | |||
// Deprecated: Use FilePV instead. | |||
type OldFilePV 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 bytes.HexBytes `json:"last_signbytes,omitempty"` | |||
PrivKey crypto.PrivKey `json:"priv_key"` | |||
filePath string | |||
} | |||
// LoadOldFilePV loads an OldFilePV from the filePath. | |||
func LoadOldFilePV(filePath string) (*OldFilePV, error) { | |||
pvJSONBytes, err := ioutil.ReadFile(filePath) | |||
if err != nil { | |||
return nil, err | |||
} | |||
pv := &OldFilePV{} | |||
err = cdc.UnmarshalJSON(pvJSONBytes, &pv) | |||
if err != nil { | |||
return nil, err | |||
} | |||
// overwrite pubkey and address for convenience | |||
pv.PubKey = pv.PrivKey.PubKey() | |||
pv.Address = pv.PubKey.Address() | |||
pv.filePath = filePath | |||
return pv, nil | |||
} | |||
// Upgrade convets the OldFilePV to the new FilePV, separating the immutable and mutable components, | |||
// and persisting them to the keyFilePath and stateFilePath, respectively. | |||
// It renames the original file by adding ".bak". | |||
func (oldFilePV *OldFilePV) Upgrade(keyFilePath, stateFilePath string) *FilePV { | |||
privKey := oldFilePV.PrivKey | |||
pvKey := FilePVKey{ | |||
PrivKey: privKey, | |||
PubKey: privKey.PubKey(), | |||
Address: privKey.PubKey().Address(), | |||
filePath: keyFilePath, | |||
} | |||
pvState := FilePVLastSignState{ | |||
Height: oldFilePV.LastHeight, | |||
Round: oldFilePV.LastRound, | |||
Step: oldFilePV.LastStep, | |||
Signature: oldFilePV.LastSignature, | |||
SignBytes: oldFilePV.LastSignBytes, | |||
filePath: stateFilePath, | |||
} | |||
// Save the new PV files | |||
pv := &FilePV{ | |||
Key: pvKey, | |||
LastSignState: pvState, | |||
} | |||
pv.Save() | |||
// Rename the old PV file | |||
err := os.Rename(oldFilePV.filePath, oldFilePV.filePath+".bak") | |||
if err != nil { | |||
panic(err) | |||
} | |||
return pv | |||
} |
@ -1,84 +0,0 @@ | |||
package privval_test | |||
import ( | |||
"io/ioutil" | |||
"os" | |||
"testing" | |||
"github.com/stretchr/testify/assert" | |||
"github.com/stretchr/testify/require" | |||
"github.com/tendermint/tendermint/privval" | |||
) | |||
const lastSignBytes = "750802110500000000000000220B08B398F3E00510F48DA6402A480A20F" + | |||
"C258973076512999C3E6839A22E9FBDB1B77CF993E8A9955412A41A59D4" + | |||
"CAD312240A20C971B286ACB8AAA6FCA0365EB0A660B189EDC08B46B5AF2" + | |||
"995DEFA51A28D215B10013211746573742D636861696E2D533245415533" | |||
const oldPrivvalContent = `{ | |||
"address": "1D8089FAFDFAE4A637F3D616E17B92905FA2D91D", | |||
"pub_key": { | |||
"type": "tendermint/PubKeyEd25519", | |||
"value": "r3Yg2AhDZ745CNTpavsGU+mRZ8WpRXqoJuyqjN8mJq0=" | |||
}, | |||
"last_height": "5", | |||
"last_round": "0", | |||
"last_step": 3, | |||
"last_signature": "CTr7b9ZQlrJJf+12rPl5t/YSCUc/KqV7jQogCfFJA24e7hof69X6OMT7eFLVQHyodPjD/QTA298XHV5ejxInDQ==", | |||
"last_signbytes": "` + lastSignBytes + `", | |||
"priv_key": { | |||
"type": "tendermint/PrivKeyEd25519", | |||
"value": "7MwvTGEWWjsYwjn2IpRb+GYsWi9nnFsw8jPLLY1UtP6vdiDYCENnvjkI1Olq+wZT6ZFnxalFeqgm7KqM3yYmrQ==" | |||
} | |||
}` | |||
func TestLoadAndUpgrade(t *testing.T) { | |||
oldFilePath := initTmpOldFile(t) | |||
defer os.Remove(oldFilePath) | |||
newStateFile, err := ioutil.TempFile("", "priv_validator_state*.json") | |||
defer os.Remove(newStateFile.Name()) | |||
require.NoError(t, err) | |||
newKeyFile, err := ioutil.TempFile("", "priv_validator_key*.json") | |||
defer os.Remove(newKeyFile.Name()) | |||
require.NoError(t, err) | |||
oldPV, err := privval.LoadOldFilePV(oldFilePath) | |||
assert.NoError(t, err) | |||
newPV := oldPV.Upgrade(newKeyFile.Name(), newStateFile.Name()) | |||
assertEqualPV(t, oldPV, newPV) | |||
assert.NoError(t, err) | |||
upgradedPV := privval.LoadFilePV(newKeyFile.Name(), newStateFile.Name()) | |||
assertEqualPV(t, oldPV, upgradedPV) | |||
oldPV, err = privval.LoadOldFilePV(oldFilePath + ".bak") | |||
require.NoError(t, err) | |||
assertEqualPV(t, oldPV, upgradedPV) | |||
} | |||
func assertEqualPV(t *testing.T, oldPV *privval.OldFilePV, newPV *privval.FilePV) { | |||
assert.Equal(t, oldPV.Address, newPV.Key.Address) | |||
assert.Equal(t, oldPV.Address, newPV.GetAddress()) | |||
assert.Equal(t, oldPV.PubKey, newPV.Key.PubKey) | |||
npv, err := newPV.GetPubKey() | |||
require.NoError(t, err) | |||
assert.Equal(t, oldPV.PubKey, npv) | |||
assert.Equal(t, oldPV.PrivKey, newPV.Key.PrivKey) | |||
assert.Equal(t, oldPV.LastHeight, newPV.LastSignState.Height) | |||
assert.Equal(t, oldPV.LastRound, newPV.LastSignState.Round) | |||
assert.Equal(t, oldPV.LastSignature, newPV.LastSignState.Signature) | |||
assert.Equal(t, oldPV.LastSignBytes, newPV.LastSignState.SignBytes) | |||
assert.Equal(t, oldPV.LastStep, newPV.LastSignState.Step) | |||
} | |||
func initTmpOldFile(t *testing.T) string { | |||
tmpFile, err := ioutil.TempFile("", "priv_validator_*.json") | |||
require.NoError(t, err) | |||
t.Logf("created test file %s", tmpFile.Name()) | |||
_, err = tmpFile.WriteString(oldPrivvalContent) | |||
require.NoError(t, err) | |||
return tmpFile.Name() | |||
} |
@ -1,45 +0,0 @@ | |||
package main | |||
import ( | |||
"fmt" | |||
"os" | |||
"github.com/tendermint/tendermint/libs/log" | |||
"github.com/tendermint/tendermint/privval" | |||
) | |||
var ( | |||
logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) | |||
) | |||
func main() { | |||
args := os.Args[1:] | |||
if len(args) != 3 { | |||
fmt.Println("Expected three args: <old path> <new key path> <new state path>") | |||
fmt.Println( | |||
"Eg. ~/.tendermint/config/priv_validator.json" + | |||
" ~/.tendermint/config/priv_validator_key.json" + | |||
" ~/.tendermint/data/priv_validator_state.json", | |||
) | |||
os.Exit(1) | |||
} | |||
err := loadAndUpgrade(args[0], args[1], args[2]) | |||
if err != nil { | |||
fmt.Println(err) | |||
os.Exit(1) | |||
} | |||
} | |||
func loadAndUpgrade(oldPVPath, newPVKeyPath, newPVStatePath string) error { | |||
oldPV, err := privval.LoadOldFilePV(oldPVPath) | |||
if err != nil { | |||
return fmt.Errorf("error reading OldPrivValidator from %v: %v", oldPVPath, err) | |||
} | |||
logger.Info("Upgrading PrivValidator file", | |||
"old", oldPVPath, | |||
"newKey", newPVKeyPath, | |||
"newState", newPVStatePath, | |||
) | |||
oldPV.Upgrade(newPVKeyPath, newPVStatePath) | |||
return nil | |||
} |
@ -1,129 +0,0 @@ | |||
package main | |||
import ( | |||
"fmt" | |||
"io/ioutil" | |||
"os" | |||
"testing" | |||
"github.com/stretchr/testify/assert" | |||
"github.com/stretchr/testify/require" | |||
"github.com/tendermint/tendermint/privval" | |||
) | |||
const lastSignBytes = "750802110500000000000000220B08B398F3E00510F48DA6402A480A20FC25" + | |||
"8973076512999C3E6839A22E9FBDB1B77CF993E8A9955412A41A59D4CAD312240A20C971B286ACB8AA" + | |||
"A6FCA0365EB0A660B189EDC08B46B5AF2995DEFA51A28D215B10013211746573742D636861696E2D533245415533" | |||
const oldPrivvalContent = `{ | |||
"address": "1D8089FAFDFAE4A637F3D616E17B92905FA2D91D", | |||
"pub_key": { | |||
"type": "tendermint/PubKeyEd25519", | |||
"value": "r3Yg2AhDZ745CNTpavsGU+mRZ8WpRXqoJuyqjN8mJq0=" | |||
}, | |||
"last_height": "5", | |||
"last_round": "0", | |||
"last_step": 3, | |||
"last_signature": "CTr7b9ZQlrJJf+12rPl5t/YSCUc/KqV7jQogCfFJA24e7hof69X6OMT7eFLVQHyodPjD/QTA298XHV5ejxInDQ==", | |||
"last_signbytes": "` + lastSignBytes + `", | |||
"priv_key": { | |||
"type": "tendermint/PrivKeyEd25519", | |||
"value": "7MwvTGEWWjsYwjn2IpRb+GYsWi9nnFsw8jPLLY1UtP6vdiDYCENnvjkI1Olq+wZT6ZFnxalFeqgm7KqM3yYmrQ==" | |||
} | |||
}` | |||
func TestLoadAndUpgrade(t *testing.T) { | |||
oldFilePath := initTmpOldFile(t) | |||
defer os.Remove(oldFilePath) | |||
newStateFile, err := ioutil.TempFile("", "priv_validator_state*.json") | |||
defer os.Remove(newStateFile.Name()) | |||
require.NoError(t, err) | |||
newKeyFile, err := ioutil.TempFile("", "priv_validator_key*.json") | |||
defer os.Remove(newKeyFile.Name()) | |||
require.NoError(t, err) | |||
emptyOldFile, err := ioutil.TempFile("", "priv_validator_empty*.json") | |||
require.NoError(t, err) | |||
defer os.Remove(emptyOldFile.Name()) | |||
type args struct { | |||
oldPVPath string | |||
newPVKeyPath string | |||
newPVStatePath string | |||
} | |||
tests := []struct { | |||
name string | |||
args args | |||
wantErr bool | |||
wantPanic bool | |||
}{ | |||
{"successful upgrade", | |||
args{oldPVPath: oldFilePath, newPVKeyPath: newKeyFile.Name(), newPVStatePath: newStateFile.Name()}, | |||
false, false, | |||
}, | |||
{"unsuccessful upgrade: empty old privval file", | |||
args{oldPVPath: emptyOldFile.Name(), newPVKeyPath: newKeyFile.Name(), newPVStatePath: newStateFile.Name()}, | |||
true, false, | |||
}, | |||
{"unsuccessful upgrade: invalid new paths (1/3)", | |||
args{oldPVPath: oldFilePath, newPVKeyPath: "", newPVStatePath: newStateFile.Name()}, | |||
false, true, | |||
}, | |||
{"unsuccessful upgrade: invalid new paths (2/3)", | |||
args{oldPVPath: oldFilePath, newPVKeyPath: newKeyFile.Name(), newPVStatePath: ""}, | |||
false, true, | |||
}, | |||
{"unsuccessful upgrade: invalid new paths (3/3)", | |||
args{oldPVPath: oldFilePath, newPVKeyPath: "", newPVStatePath: ""}, | |||
false, true, | |||
}, | |||
} | |||
for _, tt := range tests { | |||
tt := tt | |||
t.Run(tt.name, func(t *testing.T) { | |||
// need to re-write the file everytime because upgrading renames it | |||
err := ioutil.WriteFile(oldFilePath, []byte(oldPrivvalContent), 0600) | |||
require.NoError(t, err) | |||
if tt.wantPanic { | |||
require.Panics(t, func() { loadAndUpgrade(tt.args.oldPVPath, tt.args.newPVKeyPath, tt.args.newPVStatePath) }) | |||
} else { | |||
err = loadAndUpgrade(tt.args.oldPVPath, tt.args.newPVKeyPath, tt.args.newPVStatePath) | |||
if tt.wantErr { | |||
assert.Error(t, err) | |||
fmt.Println("ERR", err) | |||
} else { | |||
assert.NoError(t, err) | |||
upgradedPV := privval.LoadFilePV(tt.args.newPVKeyPath, tt.args.newPVStatePath) | |||
oldPV, err := privval.LoadOldFilePV(tt.args.oldPVPath + ".bak") | |||
require.NoError(t, err) | |||
assert.Equal(t, oldPV.Address, upgradedPV.Key.Address) | |||
assert.Equal(t, oldPV.Address, upgradedPV.GetAddress()) | |||
assert.Equal(t, oldPV.PubKey, upgradedPV.Key.PubKey) | |||
upv, err := upgradedPV.GetPubKey() | |||
require.NoError(t, err) | |||
assert.Equal(t, oldPV.PubKey, upv) | |||
assert.Equal(t, oldPV.PrivKey, upgradedPV.Key.PrivKey) | |||
assert.Equal(t, oldPV.LastHeight, upgradedPV.LastSignState.Height) | |||
assert.Equal(t, oldPV.LastRound, upgradedPV.LastSignState.Round) | |||
assert.Equal(t, oldPV.LastSignature, upgradedPV.LastSignState.Signature) | |||
assert.Equal(t, oldPV.LastSignBytes, upgradedPV.LastSignState.SignBytes) | |||
assert.Equal(t, oldPV.LastStep, upgradedPV.LastSignState.Step) | |||
} | |||
} | |||
}) | |||
} | |||
} | |||
func initTmpOldFile(t *testing.T) string { | |||
tmpfile, err := ioutil.TempFile("", "priv_validator_*.json") | |||
require.NoError(t, err) | |||
t.Logf("created test file %s", tmpfile.Name()) | |||
_, err = tmpfile.WriteString(oldPrivvalContent) | |||
require.NoError(t, err) | |||
return tmpfile.Name() | |||
} |