diff --git a/docs/spec/blockchain/encoding.md b/docs/spec/blockchain/encoding.md index 563b0a885..2f9fcdca1 100644 --- a/docs/spec/blockchain/encoding.md +++ b/docs/spec/blockchain/encoding.md @@ -301,15 +301,15 @@ Where the `"value"` is the base64 encoding of the raw pubkey bytes, and the Signed messages (eg. votes, proposals) in the consensus are encoded using Amino. When signing, the elements of a message are re-ordered so the fixed-length fields -are first, making it easy to quickly check the version, height, round, and type. +are first, making it easy to quickly check the type, height, and round. The `ChainID` is also appended to the end. We call this encoding the SignBytes. For instance, SignBytes for a vote is the Amino encoding of the following struct: ```go type CanonicalVote struct { + Type byte Height int64 `binary:"fixed64"` Round int64 `binary:"fixed64"` - VoteType byte Timestamp time.Time BlockID CanonicalBlockID ChainID string diff --git a/types/canonical.go b/types/canonical.go index c40f35dd3..632dcb624 100644 --- a/types/canonical.go +++ b/types/canonical.go @@ -23,9 +23,9 @@ type CanonicalPartSetHeader struct { } type CanonicalProposal struct { + Type SignedMsgType // type alias for byte Height int64 `binary:"fixed64"` Round int64 `binary:"fixed64"` - Type SignedMsgType // type alias for byte POLRound int64 `binary:"fixed64"` Timestamp time.Time BlockPartsHeader CanonicalPartSetHeader @@ -34,19 +34,19 @@ type CanonicalProposal struct { } type CanonicalVote struct { + Type SignedMsgType // type alias for byte Height int64 `binary:"fixed64"` Round int64 `binary:"fixed64"` - Type SignedMsgType // type alias for byte Timestamp time.Time BlockID CanonicalBlockID ChainID string } type CanonicalHeartbeat struct { + Type byte Height int64 `binary:"fixed64"` Round int `binary:"fixed64"` - Type byte - Sequence int `binary:"fixed64"` + Sequence int `binary:"fixed64"` ValidatorAddress Address ValidatorIndex int ChainID string @@ -71,9 +71,9 @@ func CanonicalizePartSetHeader(psh PartSetHeader) CanonicalPartSetHeader { func CanonicalizeProposal(chainID string, proposal *Proposal) CanonicalProposal { return CanonicalProposal{ + Type: ProposalType, Height: proposal.Height, Round: int64(proposal.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int) - Type: ProposalType, POLRound: int64(proposal.POLRound), Timestamp: proposal.Timestamp, BlockPartsHeader: CanonicalizePartSetHeader(proposal.BlockPartsHeader), @@ -84,9 +84,9 @@ func CanonicalizeProposal(chainID string, proposal *Proposal) CanonicalProposal func CanonicalizeVote(chainID string, vote *Vote) CanonicalVote { return CanonicalVote{ + Type: vote.Type, Height: vote.Height, Round: int64(vote.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int) - Type: vote.Type, Timestamp: vote.Timestamp, BlockID: CanonicalizeBlockID(vote.BlockID), ChainID: chainID, @@ -95,9 +95,9 @@ func CanonicalizeVote(chainID string, vote *Vote) CanonicalVote { func CanonicalizeHeartbeat(chainID string, heartbeat *Heartbeat) CanonicalHeartbeat { return CanonicalHeartbeat{ + Type: byte(HeartbeatType), Height: heartbeat.Height, Round: heartbeat.Round, - Type: byte(HeartbeatType), Sequence: heartbeat.Sequence, ValidatorAddress: heartbeat.ValidatorAddress, ValidatorIndex: heartbeat.ValidatorIndex, diff --git a/types/vote_test.go b/types/vote_test.go index 066df4964..2172f0600 100644 --- a/types/vote_test.go +++ b/types/vote_test.go @@ -70,12 +70,12 @@ func TestVoteSignableTestVectors(t *testing.T) { CanonicalizeVote("", &Vote{Height: 1, Round: 1, Type: PrecommitType}), []byte{ 0x1f, // total length - 0x9, // (field_number << 3) | wire_type - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height + 0x8, // (field_number << 3) | wire_type + 0x2, // PrecommitType 0x11, // (field_number << 3) | wire_type + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height + 0x19, // (field_number << 3) | wire_type 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round - 0x18, // (field_number << 3) | wire_type - 0x2, // PrecommitType 0x22, // (field_number << 3) | wire_type // remaining fields (timestamp): 0x9, 0x9, 0x0, 0x9, 0x6e, 0x88, 0xf1, 0xff, 0xff, 0xff}, @@ -85,12 +85,12 @@ func TestVoteSignableTestVectors(t *testing.T) { CanonicalizeVote("", &Vote{Height: 1, Round: 1, Type: PrevoteType}), []byte{ 0x1f, // total length - 0x9, // (field_number << 3) | wire_type - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height + 0x8, // (field_number << 3) | wire_type + 0x1, // PrevoteType 0x11, // (field_number << 3) | wire_type + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height + 0x19, // (field_number << 3) | wire_type 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round - 0x18, // (field_number << 3) | wire_type - 0x1, // PrevoteType 0x22, // (field_number << 3) | wire_type // remaining fields (timestamp): 0x9, 0x9, 0x0, 0x9, 0x6e, 0x88, 0xf1, 0xff, 0xff, 0xff}, @@ -99,9 +99,9 @@ func TestVoteSignableTestVectors(t *testing.T) { vote, []byte{ 0x1d, // total length - 0x9, // (field_number << 3) | wire_type - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height 0x11, // (field_number << 3) | wire_type + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height + 0x19, // (field_number << 3) | wire_type 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round // remaining fields (timestamp): 0x22, @@ -112,9 +112,9 @@ func TestVoteSignableTestVectors(t *testing.T) { CanonicalizeVote("test_chain_id", &Vote{Height: 1, Round: 1}), []byte{ 0x2c, // total length - 0x9, // (field_number << 3) | wire_type - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height 0x11, // (field_number << 3) | wire_type + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height + 0x19, // (field_number << 3) | wire_type 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round // remaining fields: 0x22, // (field_number << 3) | wire_type