mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-21 07:24:36 +00:00
[R4R] Fixed sized and reordered fields for Vote/Proposal/Heartbeat SignBytes (#2598)
* WIP: switching to fixed offsets for SignBytes * add version field to sign bytes and update order * more comments on test-cases and add a tc with a chainID * remove amino:"write_empty" tag - it doesn't affect if default fixed size fields ((u)int64) are written or not - add comment about int->int64 casting * update CHANGELOG_PENDING * update documentation * add back link to issue #1622 in documentation * remove JSON tags and add (failing test-case) * fix failing test * update test-vectors due to added `Type` field * change Type field from string to byte and add new type alias - SignedMsgType replaces VoteTypePrevote, VoteTypePrecommit and adds new ProposalType to separate votes from proposal when signed - update test-vectors * fix remains from rebasing * use SignMessageType instead of byte everywhere * fixes from review
This commit is contained in:
committed by
Ethan Buchman
parent
1b51cf3f46
commit
8888595b94
@@ -410,8 +410,9 @@ must be greater than 2/3 of the total voting power of the complete validator set
|
||||
|
||||
A vote is a signed message broadcast in the consensus for a particular block at a particular height and round.
|
||||
When stored in the blockchain or propagated over the network, votes are encoded in Amino.
|
||||
For signing, votes are represented via `CanonicalVote` and also encoded using amino (protobuf compatible) via
|
||||
`Vote.SignBytes` which includes the `ChainID`.
|
||||
For signing, votes are represented via `CanonicalVote` and also encoded using amino (protobuf compatible) via
|
||||
`Vote.SignBytes` which includes the `ChainID`, and uses a different ordering of
|
||||
the fields.
|
||||
|
||||
We define a method `Verify` that returns `true` if the signature verifies against the pubkey for the `SignBytes`
|
||||
using the given ChainID:
|
||||
|
||||
@@ -300,20 +300,23 @@ 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 sorted alphabetically by key and prepended with
|
||||
a `chain_id` and `type` field.
|
||||
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.
|
||||
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 {
|
||||
ChainID string
|
||||
Type string
|
||||
BlockID CanonicalBlockID
|
||||
Height int64
|
||||
Round int
|
||||
Timestamp time.Time
|
||||
Version uint64 `binary:"fixed64"`
|
||||
Height int64 `binary:"fixed64"`
|
||||
Round int64 `binary:"fixed64"`
|
||||
VoteType byte
|
||||
Timestamp time.Time
|
||||
BlockID CanonicalBlockID
|
||||
ChainID string
|
||||
}
|
||||
```
|
||||
|
||||
NOTE: see [#1622](https://github.com/tendermint/tendermint/issues/1622) for how field ordering will change
|
||||
The field ordering and the fixed sized encoding for the first three fields is optimized to ease parsing of SignBytes
|
||||
in HSMs. It creates fixed offsets for relevant fields that need to be read in this context.
|
||||
See [#1622](https://github.com/tendermint/tendermint/issues/1622) for more details.
|
||||
|
||||
Reference in New Issue
Block a user