Revision 86adc2c89f80fa21579877d3f3e198f794e2ab9a authored by Anton Kaliaev on 13 January 2020, 07:56:48 UTC, committed by GitHub on 13 January 2020, 07:56:48 UTC
* rename adjusted to adjacent

Refs https://github.com/tendermint/tendermint/pull/3989#discussion_r352140829

* rename ErrTooMuchChange to ErrNotEnoughVotingPowerSigned

Refs https://github.com/tendermint/tendermint/pull/3989#discussion_r352142785

* verify commit is properly signed

* remove no longer trusted headers

* restore trustedHeader and trustedNextVals

* check trustedHeader using options

Refs https://github.com/tendermint/tendermint/pull/4209#issuecomment-562462165

* use correct var when checking if headers are adjacent

in bisection func
+ replace TODO with a comment

https://github.com/tendermint/tendermint/pull/3989#discussion_r352125455

* return header in VerifyHeaderAtHeight

because that way we avoid DB call

+ add godoc comments
+ check if there are no headers yet in AutoClient

https://github.com/tendermint/tendermint/pull/3989#pullrequestreview-315454506

* TestVerifyAdjacentHeaders: add 2 more test-cases

+ add TestVerifyReturnsErrorIfTrustLevelIsInvalid

* lite: avoid overflow when parsing key in db store!

* lite: rename AutoClient#Err to Errs

* lite: add a test for AutoClient

* lite: fix keyPattern and call itr.Next in db store

* lite: add two tests for db store

* lite: add TestClientRemovesNoLongerTrustedHeaders

* lite: test Client#Cleanup

* lite: test restoring trustedHeader

https://github.com/tendermint/tendermint/pull/4209#issuecomment-562462165

* lite: comment out unused code in test_helpers

* fix TestVerifyReturnsErrorIfTrustLevelIsInvalid after merge

* change defaultRemoveNoLongerTrustedHeadersPeriod

and add docs

* write more doc

* lite: uncomment testable examples

* use stdlog.Fatal to stop AutoClient tests

* make lll linter happy

* separate errors for 2 cases

- the validator set of a skipped header cannot be trusted, i.e. <1/3rd
  of h1 validator set has signed (new error, something like
  ErrNewValSetCantBeTrusted)
- the validator set is trusted but < 2/3rds has signed
  (ErrNewHeaderCantBeTrusted)

https://github.com/tendermint/tendermint/pull/4209#discussion_r360331253

* remove all headers (even the last one) that are outside

of the trusting period. By doing this, we avoid checking the
trustedHeader's hash in checkTrustedHeaderUsingOptions (case #1).

https://github.com/tendermint/tendermint/pull/4209#discussion_r360332460

* explain restoreTrustedHeaderAndNextVals better

https://github.com/tendermint/tendermint/pull/4209#discussion_r360602328

* add ConfirmationFunction option

for optionally prompting for user input Y/n before removing headers

Refs https://github.com/tendermint/tendermint/pull/4209#discussion_r360602945

* make cleaning optional

https://github.com/tendermint/tendermint/pull/4209#discussion_r364838189

* return error when user refused to remove headers

* check for double votes in VerifyCommitTrusting

* leave only ErrNewValSetCantBeTrusted error

to differenciate between h2Vals.VerifyCommit and
h1NextVals.VerifyCommitTrusting

* fix example tests

* remove unnecessary if condition

https://github.com/tendermint/tendermint/pull/4209#discussion_r365171847

It will be handled by the above switch.

* verifyCommitBasic does not depend on vals

Co-authored-by: Marko <marbar3778@yahoo.com>
1 parent db235c8
Raw File
canonical.go
package types

import (
	"time"

	"github.com/tendermint/tendermint/libs/bytes"
	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

type CanonicalBlockID struct {
	Hash        bytes.HexBytes
	PartsHeader CanonicalPartSetHeader
}

type CanonicalPartSetHeader struct {
	Hash  bytes.HexBytes
	Total int
}

type CanonicalProposal struct {
	Type      SignedMsgType // type alias for byte
	Height    int64         `binary:"fixed64"`
	Round     int64         `binary:"fixed64"`
	POLRound  int64         `binary:"fixed64"`
	BlockID   CanonicalBlockID
	Timestamp time.Time
	ChainID   string
}

type CanonicalVote struct {
	Type      SignedMsgType // type alias for byte
	Height    int64         `binary:"fixed64"`
	Round     int64         `binary:"fixed64"`
	BlockID   CanonicalBlockID
	Timestamp time.Time
	ChainID   string
}

//-----------------------------------
// Canonicalize the structs

func CanonicalizeBlockID(blockID BlockID) CanonicalBlockID {
	return CanonicalBlockID{
		Hash:        blockID.Hash,
		PartsHeader: CanonicalizePartSetHeader(blockID.PartsHeader),
	}
}

func CanonicalizePartSetHeader(psh PartSetHeader) CanonicalPartSetHeader {
	return CanonicalPartSetHeader{
		psh.Hash,
		psh.Total,
	}
}

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)
		POLRound:  int64(proposal.POLRound),
		BlockID:   CanonicalizeBlockID(proposal.BlockID),
		Timestamp: proposal.Timestamp,
		ChainID:   chainID,
	}
}

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)
		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)
}
back to top