mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 06:42:16 +00:00
Add timestamp to vote canonical encoding
This commit is contained in:
parent
7deda53b7c
commit
599673690c
@ -1,11 +1,16 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
// canonical json is go-wire's json for structs with fields in alphabetical order
|
// canonical json is go-wire's json for structs with fields in alphabetical order
|
||||||
|
|
||||||
|
// timeFormat is RFC3339Millis, used for generating the sigs
|
||||||
|
const timeFormat = "2006-01-02T15:04:05.999Z07:00"
|
||||||
|
|
||||||
type CanonicalJSONBlockID struct {
|
type CanonicalJSONBlockID struct {
|
||||||
Hash data.Bytes `json:"hash,omitempty"`
|
Hash data.Bytes `json:"hash,omitempty"`
|
||||||
PartsHeader CanonicalJSONPartSetHeader `json:"parts,omitempty"`
|
PartsHeader CanonicalJSONPartSetHeader `json:"parts,omitempty"`
|
||||||
@ -26,10 +31,11 @@ type CanonicalJSONProposal struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CanonicalJSONVote struct {
|
type CanonicalJSONVote struct {
|
||||||
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"`
|
||||||
Type byte `json:"type"`
|
Timestamp string `json:"timestamp"`
|
||||||
|
Type byte `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CanonicalJSONHeartbeat struct {
|
type CanonicalJSONHeartbeat struct {
|
||||||
@ -79,7 +85,7 @@ func CanonicalProposal(proposal *Proposal) CanonicalJSONProposal {
|
|||||||
return CanonicalJSONProposal{
|
return CanonicalJSONProposal{
|
||||||
BlockPartsHeader: CanonicalPartSetHeader(proposal.BlockPartsHeader),
|
BlockPartsHeader: CanonicalPartSetHeader(proposal.BlockPartsHeader),
|
||||||
Height: proposal.Height,
|
Height: proposal.Height,
|
||||||
Timestamp: proposal.TimeString(),
|
Timestamp: CanonicalTime(proposal.Timestamp),
|
||||||
POLBlockID: CanonicalBlockID(proposal.POLBlockID),
|
POLBlockID: CanonicalBlockID(proposal.POLBlockID),
|
||||||
POLRound: proposal.POLRound,
|
POLRound: proposal.POLRound,
|
||||||
Round: proposal.Round,
|
Round: proposal.Round,
|
||||||
@ -88,10 +94,11 @@ func CanonicalProposal(proposal *Proposal) CanonicalJSONProposal {
|
|||||||
|
|
||||||
func CanonicalVote(vote *Vote) CanonicalJSONVote {
|
func CanonicalVote(vote *Vote) CanonicalJSONVote {
|
||||||
return CanonicalJSONVote{
|
return CanonicalJSONVote{
|
||||||
CanonicalBlockID(vote.BlockID),
|
BlockID: CanonicalBlockID(vote.BlockID),
|
||||||
vote.Height,
|
Height: vote.Height,
|
||||||
vote.Round,
|
Round: vote.Round,
|
||||||
vote.Type,
|
Timestamp: CanonicalTime(vote.Timestamp),
|
||||||
|
Type: vote.Type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,3 +111,7 @@ func CanonicalHeartbeat(heartbeat *Heartbeat) CanonicalJSONHeartbeat {
|
|||||||
heartbeat.ValidatorIndex,
|
heartbeat.ValidatorIndex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CanonicalTime(t time.Time) string {
|
||||||
|
return t.Format(timeFormat)
|
||||||
|
}
|
||||||
|
@ -15,9 +15,6 @@ var (
|
|||||||
ErrInvalidBlockPartHash = errors.New("Error invalid block part hash")
|
ErrInvalidBlockPartHash = errors.New("Error invalid block part hash")
|
||||||
)
|
)
|
||||||
|
|
||||||
// TimeFormat is RFC3339Millis, used for generating the sigs
|
|
||||||
const TimeFormat = "2006-01-02T15:04:05.999Z07:00"
|
|
||||||
|
|
||||||
// Proposal defines a block proposal for the consensus.
|
// Proposal defines a block proposal for the consensus.
|
||||||
// It refers to the block only by its PartSetHeader.
|
// It refers to the block only by its PartSetHeader.
|
||||||
// It must be signed by the correct proposer for the given Height/Round
|
// It must be signed by the correct proposer for the given Height/Round
|
||||||
@ -46,16 +43,11 @@ func NewProposal(height int64, round int, blockPartsHeader PartSetHeader, polRou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimeString returns the canonical encoding of timestamp
|
|
||||||
func (p *Proposal) TimeString() string {
|
|
||||||
return p.Timestamp.Format(TimeFormat)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a string representation of the Proposal.
|
// String returns a string representation of the Proposal.
|
||||||
func (p *Proposal) String() string {
|
func (p *Proposal) String() string {
|
||||||
return fmt.Sprintf("Proposal{%v/%v %v (%v,%v) %v @ %s}",
|
return fmt.Sprintf("Proposal{%v/%v %v (%v,%v) %v @ %s}",
|
||||||
p.Height, p.Round, p.BlockPartsHeader, p.POLRound,
|
p.Height, p.Round, p.BlockPartsHeader, p.POLRound,
|
||||||
p.POLBlockID, p.Signature, p.TimeString())
|
p.POLBlockID, p.Signature, CanonicalTime(p.Timestamp))
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteSignBytes writes the Proposal bytes for signing
|
// WriteSignBytes writes the Proposal bytes for signing
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
var testProposal *Proposal
|
var testProposal *Proposal
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var stamp, err = time.Parse(TimeFormat, "2018-02-11T07:09:22.765Z")
|
var stamp, err = time.Parse(timeFormat, "2018-02-11T07:09:22.765Z")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/tendermint/go-crypto"
|
"github.com/tendermint/go-crypto"
|
||||||
"github.com/tendermint/go-wire"
|
"github.com/tendermint/go-wire"
|
||||||
@ -53,6 +54,7 @@ type Vote struct {
|
|||||||
ValidatorIndex int `json:"validator_index"`
|
ValidatorIndex int `json:"validator_index"`
|
||||||
Height int64 `json:"height"`
|
Height int64 `json:"height"`
|
||||||
Round int `json:"round"`
|
Round int `json:"round"`
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
Type byte `json:"type"`
|
Type byte `json:"type"`
|
||||||
BlockID BlockID `json:"block_id"` // zero if vote is nil.
|
BlockID BlockID `json:"block_id"` // zero if vote is nil.
|
||||||
Signature crypto.Signature `json:"signature"`
|
Signature crypto.Signature `json:"signature"`
|
||||||
@ -84,8 +86,9 @@ func (vote *Vote) String() string {
|
|||||||
cmn.PanicSanity("Unknown vote type")
|
cmn.PanicSanity("Unknown vote type")
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%v) %X %v}",
|
return fmt.Sprintf("Vote{%v:%X %v/%02d/%v(%v) %X %v @ %s}",
|
||||||
vote.ValidatorIndex, cmn.Fingerprint(vote.ValidatorAddress),
|
vote.ValidatorIndex, cmn.Fingerprint(vote.ValidatorAddress),
|
||||||
vote.Height, vote.Round, vote.Type, typeString,
|
vote.Height, vote.Round, vote.Type, typeString,
|
||||||
cmn.Fingerprint(vote.BlockID.Hash), vote.Signature)
|
cmn.Fingerprint(vote.BlockID.Hash), vote.Signature,
|
||||||
|
CanonicalTime(vote.Timestamp))
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,21 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestVoteSignable(t *testing.T) {
|
func TestVoteSignable(t *testing.T) {
|
||||||
|
var stamp, err = time.Parse(timeFormat, "2017-12-25T03:00:01.234Z")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
vote := &Vote{
|
vote := &Vote{
|
||||||
ValidatorAddress: []byte("addr"),
|
ValidatorAddress: []byte("addr"),
|
||||||
ValidatorIndex: 56789,
|
ValidatorIndex: 56789,
|
||||||
Height: 12345,
|
Height: 12345,
|
||||||
Round: 23456,
|
Round: 23456,
|
||||||
|
Timestamp: stamp,
|
||||||
Type: byte(2),
|
Type: byte(2),
|
||||||
BlockID: BlockID{
|
BlockID: BlockID{
|
||||||
Hash: []byte("hash"),
|
Hash: []byte("hash"),
|
||||||
@ -22,7 +29,7 @@ func TestVoteSignable(t *testing.T) {
|
|||||||
signBytes := SignBytes("test_chain_id", vote)
|
signBytes := SignBytes("test_chain_id", vote)
|
||||||
signStr := string(signBytes)
|
signStr := string(signBytes)
|
||||||
|
|
||||||
expected := `{"chain_id":"test_chain_id","vote":{"block_id":{"hash":"68617368","parts":{"hash":"70617274735F68617368","total":1000000}},"height":12345,"round":23456,"type":2}}`
|
expected := `{"chain_id":"test_chain_id","vote":{"block_id":{"hash":"68617368","parts":{"hash":"70617274735F68617368","total":1000000}},"height":12345,"round":23456,"timestamp":"2017-12-25T03:00:01.234Z","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