mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 06:42:16 +00:00
removed timestamp from canonical vote so they won't be signed
This commit is contained in:
parent
5ebf9b816b
commit
5fe60feb09
@ -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.
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user