mirror of
https://github.com/tendermint/tendermint.git
synced 2026-05-01 21:05:43 +00:00
Fix usage of SimpleProof for PartSet
This commit is contained in:
@@ -27,7 +27,7 @@ func SignBytes(chainID string, o Signable) []byte {
|
||||
|
||||
// HashSignBytes is a convenience method for getting the hash of the bytes of a signable
|
||||
func HashSignBytes(chainID string, o Signable) []byte {
|
||||
return merkle.HashFromBinary(SignBytes(chainID, o))
|
||||
return merkle.SimpleHashFromBinary(SignBytes(chainID, o))
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -167,10 +167,10 @@ func (conR *ConsensusReactor) Receive(chId byte, peer *p2p.Peer, msgBytes []byte
|
||||
|
||||
case *PartMessage:
|
||||
if msg.Type == partTypeProposalBlock {
|
||||
ps.SetHasProposalBlockPart(msg.Height, msg.Round, msg.Part.Index)
|
||||
ps.SetHasProposalBlockPart(msg.Height, msg.Round, msg.Part.Proof.Index)
|
||||
_, err = conR.conS.AddProposalBlockPart(msg.Height, msg.Round, msg.Part)
|
||||
} else if msg.Type == partTypeProposalPOL {
|
||||
ps.SetHasProposalPOLPart(msg.Height, msg.Round, msg.Part.Index)
|
||||
ps.SetHasProposalPOLPart(msg.Height, msg.Round, msg.Part.Proof.Index)
|
||||
_, err = conR.conS.AddProposalPOLPart(msg.Height, msg.Round, msg.Part)
|
||||
} else {
|
||||
log.Warn(Fmt("Unknown part type %v", msg.Type))
|
||||
|
||||
@@ -27,6 +27,7 @@ package merkle
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/tendermint/binary"
|
||||
)
|
||||
@@ -89,11 +90,11 @@ func SimpleHashFromHashables(items []Hashable) []byte {
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
type SimpleProof struct {
|
||||
Index uint
|
||||
Total uint
|
||||
LeafHash []byte
|
||||
InnerHashes [][]byte // Hashes from leaf's sibling to a root's child.
|
||||
RootHash []byte
|
||||
Index uint `json:"index"`
|
||||
Total uint `json:"total"`
|
||||
LeafHash []byte `json:"leaf_hash"`
|
||||
InnerHashes [][]byte `json:"inner_hashes"` // Hashes from leaf's sibling to a root's child.
|
||||
RootHash []byte `json:"root_hash"`
|
||||
}
|
||||
|
||||
// proofs[0] is the proof for items[0].
|
||||
@@ -131,6 +132,26 @@ func (sp *SimpleProof) Verify(leafHash []byte, rootHash []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (sp *SimpleProof) String() string {
|
||||
return sp.StringIndented("")
|
||||
}
|
||||
|
||||
func (sp *SimpleProof) StringIndented(indent string) string {
|
||||
return fmt.Sprintf(`SimpleProof{
|
||||
%s Index: %v
|
||||
%s Total: %v
|
||||
%s LeafHash: %X
|
||||
%s InnerHashes: %X
|
||||
%s RootHash: %X
|
||||
%s}`,
|
||||
indent, sp.Index,
|
||||
indent, sp.Total,
|
||||
indent, sp.LeafHash,
|
||||
indent, sp.InnerHashes,
|
||||
indent, sp.RootHash,
|
||||
indent)
|
||||
}
|
||||
|
||||
// Use the leafHash and innerHashes to get the root merkle hash.
|
||||
// If the length of the innerHashes slice isn't exactly correct, the result is nil.
|
||||
func computeHashFromInnerHashes(index uint, total uint, leafHash []byte, innerHashes [][]byte) []byte {
|
||||
|
||||
@@ -126,7 +126,7 @@ func (s *State) Hash() []byte {
|
||||
s.validatorInfos,
|
||||
s.nameReg,
|
||||
}
|
||||
return merkle.HashFromHashables(hashables)
|
||||
return merkle.SimpleHashFromHashables(hashables)
|
||||
}
|
||||
|
||||
// Mutates the block in place and updates it with new state hash.
|
||||
|
||||
@@ -129,7 +129,7 @@ func (valSet *ValidatorSet) Hash() []byte {
|
||||
for i, val := range valSet.Validators {
|
||||
hashables[i] = val
|
||||
}
|
||||
return merkle.HashFromHashables(hashables)
|
||||
return merkle.SimpleHashFromHashables(hashables)
|
||||
}
|
||||
|
||||
func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
|
||||
|
||||
@@ -72,7 +72,7 @@ func (b *Block) Hash() []byte {
|
||||
|
||||
// Merkle hash from subhashes.
|
||||
hashes := [][]byte{hashHeader, hashValidation, hashData}
|
||||
return merkle.HashFromHashes(hashes)
|
||||
return merkle.SimpleHashFromHashes(hashes)
|
||||
}
|
||||
|
||||
func (b *Block) MakePartSet() *PartSet {
|
||||
@@ -233,7 +233,7 @@ func (v *Validation) Hash() []byte {
|
||||
for i, commit := range v.Commits {
|
||||
bs[i] = commit
|
||||
}
|
||||
v.hash = merkle.HashFromBinaries(bs)
|
||||
v.hash = merkle.SimpleHashFromBinaries(bs)
|
||||
}
|
||||
return v.hash
|
||||
}
|
||||
@@ -278,7 +278,7 @@ func (data *Data) Hash() []byte {
|
||||
for i, tx := range data.Txs {
|
||||
bs[i] = account.SignBytes(config.GetString("chain_id"), tx)
|
||||
}
|
||||
data.hash = merkle.HashFromBinaries(bs)
|
||||
data.hash = merkle.SimpleHashFromBinaries(bs)
|
||||
}
|
||||
return data.hash
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/tendermint/tendermint/binary"
|
||||
@@ -20,13 +19,12 @@ const (
|
||||
|
||||
var (
|
||||
ErrPartSetUnexpectedIndex = errors.New("Error part set unexpected index")
|
||||
ErrPartSetInvalidTrail = errors.New("Error part set invalid trail")
|
||||
ErrPartSetInvalidProof = errors.New("Error part set invalid proof")
|
||||
)
|
||||
|
||||
type Part struct {
|
||||
Index uint `json:"index"`
|
||||
Trail [][]byte `json:"trail"`
|
||||
Bytes []byte `json:"bytes"`
|
||||
Proof merkle.SimpleProof `json:"proof"`
|
||||
Bytes []byte `json:"bytes"`
|
||||
|
||||
// Cache
|
||||
hash []byte
|
||||
@@ -51,18 +49,12 @@ func (part *Part) String() string {
|
||||
}
|
||||
|
||||
func (part *Part) StringIndented(indent string) string {
|
||||
trailStrings := make([]string, len(part.Trail))
|
||||
for i, hash := range part.Trail {
|
||||
trailStrings[i] = fmt.Sprintf("%X", hash)
|
||||
}
|
||||
return fmt.Sprintf(`Part{
|
||||
%s Index: %v
|
||||
%s Trail:
|
||||
%s %v
|
||||
%s Proof: %v
|
||||
%s Bytes: %X
|
||||
%s}`,
|
||||
indent, part.Index,
|
||||
indent,
|
||||
indent, strings.Join(trailStrings, "\n"+indent+" "),
|
||||
indent, part.Proof.StringIndented(indent+" "),
|
||||
indent, part.Bytes,
|
||||
indent)
|
||||
}
|
||||
|
||||
@@ -111,21 +103,20 @@ func NewPartSetFromData(data []byte) *PartSet {
|
||||
partsBitArray := NewBitArray(uint(total))
|
||||
for i := 0; i < total; i++ {
|
||||
part := &Part{
|
||||
Index: uint(i),
|
||||
Bytes: data[i*partSize : MinInt(len(data), (i+1)*partSize)],
|
||||
}
|
||||
parts[i] = part
|
||||
parts_[i] = part
|
||||
partsBitArray.SetIndex(uint(i), true)
|
||||
}
|
||||
// Compute merkle trails
|
||||
trails, rootTrail := merkle.HashTrailsFromHashables(parts_)
|
||||
// Compute merkle proofs
|
||||
proofs := merkle.SimpleProofsFromHashables(parts_)
|
||||
for i := 0; i < total; i++ {
|
||||
parts[i].Trail = trails[i].Flatten()
|
||||
parts[i].Proof = *proofs[i]
|
||||
}
|
||||
return &PartSet{
|
||||
total: uint(total),
|
||||
hash: rootTrail.Hash,
|
||||
hash: proofs[0].RootHash,
|
||||
parts: parts,
|
||||
partsBitArray: partsBitArray,
|
||||
count: uint(total),
|
||||
@@ -201,23 +192,23 @@ func (ps *PartSet) AddPart(part *Part) (bool, error) {
|
||||
defer ps.mtx.Unlock()
|
||||
|
||||
// Invalid part index
|
||||
if part.Index >= ps.total {
|
||||
if part.Proof.Index >= ps.total {
|
||||
return false, ErrPartSetUnexpectedIndex
|
||||
}
|
||||
|
||||
// If part already exists, return false.
|
||||
if ps.parts[part.Index] != nil {
|
||||
if ps.parts[part.Proof.Index] != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Check hash trail
|
||||
if !merkle.VerifyHashTrail(uint(part.Index), uint(ps.total), part.Hash(), part.Trail, ps.hash) {
|
||||
return false, ErrPartSetInvalidTrail
|
||||
// Check hash proof
|
||||
if !part.Proof.Verify(part.Hash(), ps.Hash()) {
|
||||
return false, ErrPartSetInvalidProof
|
||||
}
|
||||
|
||||
// Add part
|
||||
ps.parts[part.Index] = part
|
||||
ps.partsBitArray.SetIndex(uint(part.Index), true)
|
||||
ps.parts[part.Proof.Index] = part
|
||||
ps.partsBitArray.SetIndex(uint(part.Proof.Index), true)
|
||||
ps.count++
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ func TestBasicPartSet(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestWrongTrail(t *testing.T) {
|
||||
func TestWrongProof(t *testing.T) {
|
||||
|
||||
// Construct random data of size partSize * 100
|
||||
data := RandBytes(partSize * 100)
|
||||
@@ -69,7 +69,7 @@ func TestWrongTrail(t *testing.T) {
|
||||
|
||||
// Test adding a part with wrong trail.
|
||||
part := partSet.GetPart(0)
|
||||
part.Trail[0][0] += byte(0x01)
|
||||
part.Proof.InnerHashes[0][0] += byte(0x01)
|
||||
added, err := partSet2.AddPart(part)
|
||||
if added || err == nil {
|
||||
t.Errorf("Expected to fail adding a part with bad trail.")
|
||||
|
||||
Reference in New Issue
Block a user