mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-20 15:04:22 +00:00
WIP
This commit is contained in:
@@ -403,6 +403,18 @@ func (h *Header) Populate(
|
||||
h.ProposerAddress = proposerAddress
|
||||
}
|
||||
|
||||
// NOTE: While it's possible to make this faster via a custom implementation,
|
||||
// (or naively via a struct copy, though this isn't yet a frozen design goal),
|
||||
// for now use hashes in case of any issues that may arise in implementation.
|
||||
func (h *Header) Equal(h2 *Header) bool {
|
||||
h1Hash := h.Hash()
|
||||
if h1Hash == nil {
|
||||
panic("incomplete heaeders cannot be compared")
|
||||
}
|
||||
h2Hash := h2.Hash()
|
||||
return bytes.Compare(h1Hash, h2Hash) == 0
|
||||
}
|
||||
|
||||
// Hash returns the hash of the header.
|
||||
// It computes a Merkle tree from the header fields
|
||||
// ordered as they appear in the Header.
|
||||
@@ -600,6 +612,18 @@ func (commit *Commit) ValidateBasic() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// NOTE: While it's possible to make this faster via a custom implementation,
|
||||
// (naively via a struct copy won't work due to the volatile fields),
|
||||
// for now use hashes in case of any issues that may arise in implementation.
|
||||
func (commit *Commit) Equal(commit2 *Commit) bool {
|
||||
c1Hash := commit.Hash()
|
||||
if c1Hash == nil {
|
||||
panic("incomplete commit cannot be compared")
|
||||
}
|
||||
c2Hash := commit2.Hash()
|
||||
return bytes.Compare(c1Hash, c2Hash) == 0
|
||||
}
|
||||
|
||||
// Hash returns the hash of the commit
|
||||
func (commit *Commit) Hash() cmn.HexBytes {
|
||||
if commit == nil {
|
||||
@@ -644,6 +668,15 @@ type SignedHeader struct {
|
||||
Commit *Commit `json:"commit"`
|
||||
}
|
||||
|
||||
// Returns true iff both the header and commit hold identical information
|
||||
// (disregarding any volatile memoized fields).
|
||||
// Header and Commit must be their final immutable forms, otherwise this
|
||||
// function will panic.
|
||||
func (sh SignedHeader) Equal(sh2 SignedHeader) bool {
|
||||
return sh.Header.Equal(sh2.Header) &&
|
||||
sh.Commit.Equal(sh2.Commit)
|
||||
}
|
||||
|
||||
// ValidateBasic does basic consistency checks and makes sure the header
|
||||
// and commit are consistent.
|
||||
//
|
||||
|
||||
+15
-15
@@ -416,15 +416,16 @@ func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height i
|
||||
return errTooMuchChange{talliedVotingPower, vals.TotalVotingPower()*2/3 + 1}
|
||||
}
|
||||
|
||||
// VerifyFutureCommit will check to see if the set would be valid with a different
|
||||
// validator set.
|
||||
// VerifyFutureCommit checks to see if a given future validator set has
|
||||
// committed a block, and whether those who signed of this future validator set
|
||||
// has sufficient overlap with this validator set.
|
||||
//
|
||||
// vals is the old validator set that we know. Over 2/3 of the power in old
|
||||
// signed this block.
|
||||
// vals is the current validator set that we know. Over 2/3 of the power in
|
||||
// this valset is expected to have signed this block.
|
||||
//
|
||||
// In Tendermint, 1/3 of the voting power can halt or fork the chain, but 1/3
|
||||
// can't make arbitrary state transitions. You still need > 2/3 Byzantine to
|
||||
// make arbitrary state transitions.
|
||||
// Justification for the 2/3: In Tendermint, 1/3 of the voting power can halt
|
||||
// or fork the chain, but 1/3 can't make arbitrary state transitions. You
|
||||
// still need > 2/3 Byzantine to make arbitrary state transitions.
|
||||
//
|
||||
// To preserve this property in the light client, we also require > 2/3 of the
|
||||
// old vals to sign the future commit at H, that way we preserve the property
|
||||
@@ -433,18 +434,17 @@ func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height i
|
||||
// > 2/3. Otherwise, the lite client isn't providing the same security
|
||||
// guarantees.
|
||||
//
|
||||
// Even if we added a slashing condition that if you sign a block header with
|
||||
// the wrong validator set, then we would only need > 1/3 of signatures from
|
||||
// the old vals on the new commit, it wouldn't be sufficient because the new
|
||||
// vals can be arbitrary and commit some arbitrary app hash.
|
||||
//
|
||||
// newSet is the validator set that signed this block. Only votes from new are
|
||||
// sufficient for 2/3 majority in the new set as well, for it to be a valid
|
||||
// commit.
|
||||
//
|
||||
// NOTE: This doesn't check whether the commit is a future commit, because the
|
||||
// current height isn't part of the ValidatorSet. Caller must check that the
|
||||
// commit height is greater than the height for this validator set.
|
||||
// NOTE: This doesn't check whether the commit is actually a future commit,
|
||||
// because the current height isn't part of the ValidatorSet. Caller must
|
||||
// check that the commit height is greater than the height for this validator
|
||||
// set.
|
||||
//
|
||||
// NOTE: This function is strictly more restrictive than merely checking
|
||||
// whether newSet.VerifyCommit(...), in fact it calls exactly that.
|
||||
func (vals *ValidatorSet) VerifyFutureCommit(newSet *ValidatorSet, chainID string,
|
||||
blockID BlockID, height int64, commit *Commit) error {
|
||||
oldVals := vals
|
||||
|
||||
Reference in New Issue
Block a user