removed timestamp from canonical vote so they won't be signed

This commit is contained in:
Jeremiah Andrews 2018-06-08 17:11:57 -07:00
parent 5ebf9b816b
commit 5fe60feb09
5 changed files with 14 additions and 48 deletions

View File

@ -268,7 +268,7 @@ We call this encoding the CanonicalSignBytes. For instance, CanonicalSignBytes f
like: like:
```json ```json
{"chain_id":"my-chain-id","vote":{"block_id":{"hash":DEADBEEF,"parts":{"hash":BEEFDEAD,"total":3}},"height":3,"round":2,"timestamp":1234567890, "type":2} {"chain_id":"my-chain-id","vote":{"block_id":{"hash":DEADBEEF,"parts":{"hash":BEEFDEAD,"total":3}},"height":3,"round":2, "type":2}
``` ```
Note how the fields within each level are sorted. Note how the fields within each level are sorted.

View File

@ -207,14 +207,10 @@ func (pv *FilePV) signVote(chainID string, vote *types.Vote) error {
// We might crash before writing to the wal, // We might crash before writing to the wal,
// causing us to try to re-sign for the same HRS. // causing us to try to re-sign for the same HRS.
// If signbytes are the same, use the last signature. // If signbytes are the same, use the last 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, pv.LastSignBytes) { if bytes.Equal(signBytes, pv.LastSignBytes) {
vote.Signature = pv.LastSignature vote.Signature = pv.LastSignature
} else if timestamp, ok := checkVotesOnlyDifferByTimestamp(pv.LastSignBytes, signBytes); ok {
vote.Timestamp = timestamp
vote.Signature = pv.LastSignature
} else { } else {
err = fmt.Errorf("Conflicting data") err = fmt.Errorf("Conflicting data")
} }
@ -292,32 +288,6 @@ func (pv *FilePV) String() string {
//------------------------------------- //-------------------------------------
// returns the timestamp from the lastSignBytes.
// returns true if the only difference in the votes is their timestamp.
func checkVotesOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) {
var lastVote, newVote types.CanonicalJSONVote
if err := cdc.UnmarshalJSON(lastSignBytes, &lastVote); err != nil {
panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into vote: %v", err))
}
if err := cdc.UnmarshalJSON(newSignBytes, &newVote); err != nil {
panic(fmt.Sprintf("signBytes cannot be unmarshalled into vote: %v", err))
}
lastTime, err := time.Parse(types.TimeFormat, lastVote.Timestamp)
if err != nil {
panic(err)
}
// set the times to the same value and check equality
now := types.CanonicalTime(time.Now())
lastVote.Timestamp = now
newVote.Timestamp = now
lastVoteBytes, _ := cdc.MarshalJSON(lastVote)
newVoteBytes, _ := cdc.MarshalJSON(newVote)
return lastTime, bytes.Equal(newVoteBytes, lastVoteBytes)
}
// returns the timestamp from the lastSignBytes. // returns the timestamp from the lastSignBytes.
// returns true if the only difference in the proposals is their timestamp // returns true if the only difference in the proposals is their timestamp
func checkProposalsOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) { func checkProposalsOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) {

View File

@ -207,7 +207,6 @@ func TestDifferByTimestamp(t *testing.T) {
signBytes := vote.SignBytes(chainID) signBytes := vote.SignBytes(chainID)
sig := vote.Signature sig := vote.Signature
timeStamp := clipToMS(vote.Timestamp)
// manipulate the timestamp. should get changed back // manipulate the timestamp. should get changed back
vote.Timestamp = vote.Timestamp.Add(time.Millisecond) vote.Timestamp = vote.Timestamp.Add(time.Millisecond)
@ -216,7 +215,6 @@ func TestDifferByTimestamp(t *testing.T) {
err = privVal.SignVote("mychainid", vote) err = privVal.SignVote("mychainid", vote)
assert.NoError(t, err, "expected no error on signing same vote") assert.NoError(t, err, "expected no error on signing same vote")
assert.Equal(t, timeStamp, vote.Timestamp)
assert.Equal(t, signBytes, vote.SignBytes(chainID)) assert.Equal(t, signBytes, vote.SignBytes(chainID))
assert.Equal(t, sig, vote.Signature) assert.Equal(t, sig, vote.Signature)
} }

View File

@ -34,13 +34,12 @@ type CanonicalJSONProposal struct {
} }
type CanonicalJSONVote struct { type CanonicalJSONVote struct {
ChainID string `json:"@chain_id"` ChainID string `json:"@chain_id"`
Type string `json:"@type"` Type string `json:"@type"`
BlockID CanonicalJSONBlockID `json:"block_id"` BlockID CanonicalJSONBlockID `json:"block_id"`
Height int64 `json:"height"` Height int64 `json:"height"`
Round int `json:"round"` Round int `json:"round"`
Timestamp string `json:"timestamp"` VoteType byte `json:"type"`
VoteType byte `json:"type"`
} }
type CanonicalJSONHeartbeat struct { type CanonicalJSONHeartbeat struct {
@ -85,13 +84,12 @@ func CanonicalProposal(chainID string, proposal *Proposal) CanonicalJSONProposal
func CanonicalVote(chainID string, vote *Vote) CanonicalJSONVote { func CanonicalVote(chainID string, vote *Vote) CanonicalJSONVote {
return CanonicalJSONVote{ return CanonicalJSONVote{
ChainID: chainID, ChainID: chainID,
Type: "vote", Type: "vote",
BlockID: CanonicalBlockID(vote.BlockID), BlockID: CanonicalBlockID(vote.BlockID),
Height: vote.Height, Height: vote.Height,
Round: vote.Round, Round: vote.Round,
Timestamp: CanonicalTime(vote.Timestamp), VoteType: vote.Type,
VoteType: vote.Type,
} }
} }

View File

@ -43,7 +43,7 @@ func TestVoteSignable(t *testing.T) {
signBytes := vote.SignBytes("test_chain_id") signBytes := vote.SignBytes("test_chain_id")
signStr := string(signBytes) signStr := string(signBytes)
expected := `{"@chain_id":"test_chain_id","@type":"vote","block_id":{"hash":"68617368","parts":{"hash":"70617274735F68617368","total":1000000}},"height":12345,"round":2,"timestamp":"2017-12-25T03:00:01.234Z","type":2}` expected := `{"@chain_id":"test_chain_id","@type":"vote","block_id":{"hash":"68617368","parts":{"hash":"70617274735F68617368","total":1000000}},"height":12345,"round":2,"type":2}`
if signStr != expected { if signStr != expected {
// NOTE: when this fails, you probably want to fix up consensus/replay_test too // NOTE: when this fails, you probably want to fix up consensus/replay_test too
t.Errorf("Got unexpected sign string for Vote. Expected:\n%v\nGot:\n%v", expected, signStr) t.Errorf("Got unexpected sign string for Vote. Expected:\n%v\nGot:\n%v", expected, signStr)