Files
tendermint/types/canonical.go
Ismail Khoffi 4774a8ec61 non breaking signbytes (#5008)
* test-vectors for backwards compatibility:

 - copy & paste test-vectors from v0.33.5 to ensure
 backwards compatibility for vote's SignBytes

* WIP: everything besides time seems to match :-/

* almost

* Found the culprit: field nums weren't consecutive ints ...

* fix order of partset header too

* this last votes-related test can easily be fixed

* some minor changes and fix last failing test

* move proto types back to stdtime, fix various linting

* use libs/protoio

* remvoe commented code

* add comments

* fix tests

* uncomment testscases

* dont ignore error panic

* fix signable test

* fix happy path testing

* fix comment

Co-authored-by: Marko Baricevic <marbar3778@yahoo.com>
2020-06-15 21:54:58 +02:00

70 lines
2.0 KiB
Go

package types
import (
"time"
tmproto "github.com/tendermint/tendermint/proto/types"
tmtime "github.com/tendermint/tendermint/types/time"
)
// Canonical* wraps the structs in types for amino encoding them for use in SignBytes / the Signable interface.
// TimeFormat is used for generating the sigs
const TimeFormat = time.RFC3339Nano
//-----------------------------------
// Canonicalize the structs
func CanonicalizeBlockID(bid tmproto.BlockID) *tmproto.CanonicalBlockID {
rbid, err := BlockIDFromProto(&bid)
if err != nil {
panic(err)
}
var cbid *tmproto.CanonicalBlockID
if rbid == nil || rbid.IsZero() {
cbid = nil
} else {
cbid = &tmproto.CanonicalBlockID{
Hash: bid.Hash,
PartsHeader: CanonicalizePartSetHeader(bid.PartsHeader),
}
}
return cbid
}
func CanonicalizePartSetHeader(psh tmproto.PartSetHeader) tmproto.CanonicalPartSetHeader {
return tmproto.CanonicalPartSetHeader(psh)
}
func CanonicalizeProposal(chainID string, proposal *tmproto.Proposal) tmproto.CanonicalProposal {
return tmproto.CanonicalProposal{
Type: tmproto.ProposalType,
Height: proposal.Height, // encoded as sfixed64
Round: int64(proposal.Round), // encoded as sfixed64
POLRound: int64(proposal.PolRound),
BlockID: CanonicalizeBlockID(proposal.BlockID),
Timestamp: proposal.Timestamp,
ChainID: chainID,
}
}
func CanonicalizeVote(chainID string, vote *tmproto.Vote) tmproto.CanonicalVote {
return tmproto.CanonicalVote{
Type: vote.Type,
Height: vote.Height, // encoded as sfixed64
Round: int64(vote.Round), // encoded as sfixed64
BlockID: CanonicalizeBlockID(vote.BlockID),
Timestamp: vote.Timestamp,
ChainID: chainID,
}
}
// CanonicalTime can be used to stringify time in a canonical way.
func CanonicalTime(t time.Time) string {
// Note that sending time over amino resets it to
// local time, we need to force UTC here, so the
// signatures match
return tmtime.Canonical(t).Format(TimeFormat)
}