mirror of
https://github.com/tendermint/tendermint.git
synced 2026-06-08 07:12:36 +00:00
check *parts.rootHash before sending
This commit is contained in:
@@ -147,6 +147,13 @@ func (ps *PartSet) RootHash() []byte {
|
||||
return ps.rootHash
|
||||
}
|
||||
|
||||
func (ps *PartSet) HashesTo(rootHash []byte) bool {
|
||||
if ps == nil {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(ps.rootHash, rootHash)
|
||||
}
|
||||
|
||||
func (ps *PartSet) Count() uint16 {
|
||||
if ps == nil {
|
||||
return 0
|
||||
|
||||
@@ -500,17 +500,17 @@ OUTER_LOOP:
|
||||
rs := conR.conS.GetRoundState()
|
||||
prs := ps.GetRoundState()
|
||||
|
||||
// If ProposalBlockHash matches, send parts?
|
||||
// Send proposal Block parts?
|
||||
// NOTE: if we or peer is at RoundStepCommit*, the round
|
||||
// won't necessarily match, but that's OK.
|
||||
if rs.ProposalBlock.HashesTo(prs.ProposalBlockHash) {
|
||||
if index, ok := rs.ProposalBlockPartSet.BitArray().Sub(
|
||||
if rs.ProposalBlockParts.HashesTo(prs.ProposalBlockPartsHash) {
|
||||
if index, ok := rs.ProposalBlockParts.BitArray().Sub(
|
||||
prs.ProposalBlockBitArray).PickRandom(); ok {
|
||||
msg := &PartMessage{
|
||||
Height: rs.Height,
|
||||
Round: rs.Round,
|
||||
Type: partTypeProposalBlock,
|
||||
Part: rs.ProposalBlockPartSet.GetPart(uint16(index)),
|
||||
Part: rs.ProposalBlockParts.GetPart(uint16(index)),
|
||||
}
|
||||
peer.Send(DataCh, msg)
|
||||
ps.SetHasProposalBlockPart(rs.Height, rs.Round, uint16(index))
|
||||
@@ -532,15 +532,15 @@ OUTER_LOOP:
|
||||
continue OUTER_LOOP
|
||||
}
|
||||
|
||||
// Send proposal POL part?
|
||||
if rs.ProposalPOLPartSet != nil {
|
||||
if index, ok := rs.ProposalPOLPartSet.BitArray().Sub(
|
||||
// Send proposal POL parts?
|
||||
if rs.ProposalPOLParts.HashesTo(prs.ProposalPOLPartsHash) {
|
||||
if index, ok := rs.ProposalPOLParts.BitArray().Sub(
|
||||
prs.ProposalPOLBitArray).PickRandom(); ok {
|
||||
msg := &PartMessage{
|
||||
Height: rs.Height,
|
||||
Round: rs.Round,
|
||||
Type: partTypeProposalPOL,
|
||||
Part: rs.ProposalPOLPartSet.GetPart(uint16(index)),
|
||||
Part: rs.ProposalPOLParts.GetPart(uint16(index)),
|
||||
}
|
||||
peer.Send(DataCh, msg)
|
||||
ps.SetHasProposalPOLPart(rs.Height, rs.Round, uint16(index))
|
||||
@@ -642,18 +642,18 @@ OUTER_LOOP:
|
||||
|
||||
// Read only when returned by PeerState.GetRoundState().
|
||||
type PeerRoundState struct {
|
||||
Height uint32 // Height peer is at
|
||||
Round uint16 // Round peer is at
|
||||
Step RoundStep // Step peer is at
|
||||
StartTime time.Time // Estimated start of round 0 at this height
|
||||
Proposal bool // True if peer has proposal for this round
|
||||
ProposalBlockHash []byte // Block parts merkle root
|
||||
ProposalBlockBitArray BitArray // Block parts bitarray
|
||||
ProposalPOLHash []byte // POL parts merkle root
|
||||
ProposalPOLBitArray BitArray // POL parts bitarray
|
||||
Prevotes BitArray // All votes peer has for this round
|
||||
Precommits BitArray // All precommits peer has for this round
|
||||
Commits BitArray // All commits peer has for this height
|
||||
Height uint32 // Height peer is at
|
||||
Round uint16 // Round peer is at
|
||||
Step RoundStep // Step peer is at
|
||||
StartTime time.Time // Estimated start of round 0 at this height
|
||||
Proposal bool // True if peer has proposal for this round
|
||||
ProposalBlockPartsHash []byte // Block parts merkle root
|
||||
ProposalBlockBitArray BitArray // Block parts bitarray
|
||||
ProposalPOLPartsHash []byte // POL parts merkle root
|
||||
ProposalPOLBitArray BitArray // POL parts bitarray
|
||||
Prevotes BitArray // All votes peer has for this round
|
||||
Precommits BitArray // All precommits peer has for this round
|
||||
Commits BitArray // All commits peer has for this height
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -693,7 +693,9 @@ func (ps *PeerState) SetHasProposal(proposal *Proposal) {
|
||||
}
|
||||
|
||||
ps.Proposal = true
|
||||
ps.ProposalBlockPartsHash = proposal.BlockPartsHash
|
||||
ps.ProposalBlockBitArray = NewBitArray(uint(proposal.BlockPartsTotal))
|
||||
ps.ProposalPOLPartsHash = proposal.POLPartsHash
|
||||
ps.ProposalPOLBitArray = NewBitArray(uint(proposal.POLPartsTotal))
|
||||
}
|
||||
|
||||
@@ -774,9 +776,9 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage, rs *Roun
|
||||
ps.StartTime = startTime
|
||||
if psHeight != msg.Height || psRound != msg.Round {
|
||||
ps.Proposal = false
|
||||
ps.ProposalBlockHash = nil
|
||||
ps.ProposalBlockPartsHash = nil
|
||||
ps.ProposalBlockBitArray = BitArray{}
|
||||
ps.ProposalPOLHash = nil
|
||||
ps.ProposalPOLPartsHash = nil
|
||||
ps.ProposalPOLBitArray = BitArray{}
|
||||
// We'll update the BitArray capacity later.
|
||||
ps.Prevotes = BitArray{}
|
||||
|
||||
@@ -49,25 +49,25 @@ var (
|
||||
|
||||
// Immutable when returned from ConsensusState.GetRoundState()
|
||||
type RoundState struct {
|
||||
Height uint32 // Height we are working on
|
||||
Round uint16
|
||||
Step RoundStep
|
||||
StartTime time.Time
|
||||
CommitTime time.Time // Time when +2/3 commits were found
|
||||
Validators *state.ValidatorSet
|
||||
Proposal *Proposal
|
||||
ProposalBlock *Block
|
||||
ProposalBlockPartSet *PartSet
|
||||
ProposalPOL *POL
|
||||
ProposalPOLPartSet *PartSet
|
||||
LockedBlock *Block
|
||||
LockedBlockPartSet *PartSet
|
||||
LockedPOL *POL // Rarely needed, so no LockedPOLPartSet.
|
||||
Prevotes *VoteSet
|
||||
Precommits *VoteSet
|
||||
Commits *VoteSet
|
||||
LastCommits *VoteSet
|
||||
PrivValidator *PrivValidator
|
||||
Height uint32 // Height we are working on
|
||||
Round uint16
|
||||
Step RoundStep
|
||||
StartTime time.Time
|
||||
CommitTime time.Time // Time when +2/3 commits were found
|
||||
Validators *state.ValidatorSet
|
||||
Proposal *Proposal
|
||||
ProposalBlock *Block
|
||||
ProposalBlockParts *PartSet
|
||||
ProposalPOL *POL
|
||||
ProposalPOLParts *PartSet
|
||||
LockedBlock *Block
|
||||
LockedBlockParts *PartSet
|
||||
LockedPOL *POL // Rarely needed, so no LockedPOLParts.
|
||||
Prevotes *VoteSet
|
||||
Precommits *VoteSet
|
||||
Commits *VoteSet
|
||||
LastCommits *VoteSet
|
||||
PrivValidator *PrivValidator
|
||||
}
|
||||
|
||||
func (rs *RoundState) String() string {
|
||||
@@ -95,9 +95,9 @@ func (rs *RoundState) StringWithIndent(indent string) string {
|
||||
indent, rs.CommitTime,
|
||||
indent, rs.Validators.StringWithIndent(indent+" "),
|
||||
indent, rs.Proposal,
|
||||
indent, rs.ProposalBlockPartSet.Description(), rs.ProposalBlock.Description(),
|
||||
indent, rs.ProposalPOLPartSet.Description(), rs.ProposalPOL.Description(),
|
||||
indent, rs.LockedBlockPartSet.Description(), rs.LockedBlock.Description(),
|
||||
indent, rs.ProposalBlockParts.Description(), rs.ProposalBlock.Description(),
|
||||
indent, rs.ProposalPOLParts.Description(), rs.ProposalPOL.Description(),
|
||||
indent, rs.LockedBlockParts.Description(), rs.LockedBlock.Description(),
|
||||
indent, rs.LockedPOL.Description(),
|
||||
indent, rs.Prevotes.StringWithIndent(indent+" "),
|
||||
indent, rs.Precommits.StringWithIndent(indent+" "),
|
||||
@@ -163,11 +163,11 @@ func (cs *ConsensusState) updateToState(state *state.State) {
|
||||
cs.Validators = validators
|
||||
cs.Proposal = nil
|
||||
cs.ProposalBlock = nil
|
||||
cs.ProposalBlockPartSet = nil
|
||||
cs.ProposalBlockParts = nil
|
||||
cs.ProposalPOL = nil
|
||||
cs.ProposalPOLPartSet = nil
|
||||
cs.ProposalPOLParts = nil
|
||||
cs.LockedBlock = nil
|
||||
cs.LockedBlockPartSet = nil
|
||||
cs.LockedBlockParts = nil
|
||||
cs.LockedPOL = nil
|
||||
cs.Prevotes = NewVoteSet(height, 0, VoteTypePrevote, validators)
|
||||
cs.Precommits = NewVoteSet(height, 0, VoteTypePrecommit, validators)
|
||||
@@ -207,9 +207,9 @@ func (cs *ConsensusState) setupRound(round uint16) {
|
||||
cs.Validators = validators
|
||||
cs.Proposal = nil
|
||||
cs.ProposalBlock = nil
|
||||
cs.ProposalBlockPartSet = nil
|
||||
cs.ProposalBlockParts = nil
|
||||
cs.ProposalPOL = nil
|
||||
cs.ProposalPOLPartSet = nil
|
||||
cs.ProposalPOLParts = nil
|
||||
cs.Prevotes = NewVoteSet(cs.Height, round, VoteTypePrevote, validators)
|
||||
cs.Prevotes.AddFromCommits(cs.Commits)
|
||||
cs.Precommits = NewVoteSet(cs.Height, round, VoteTypePrecommit, validators)
|
||||
@@ -237,15 +237,15 @@ func (cs *ConsensusState) RunActionPropose(height uint32, round uint16) {
|
||||
}
|
||||
|
||||
var block *Block
|
||||
var blockPartSet *PartSet
|
||||
var blockParts *PartSet
|
||||
var pol *POL
|
||||
var polPartSet *PartSet
|
||||
var polParts *PartSet
|
||||
|
||||
// Decide on block and POL
|
||||
if cs.LockedBlock != nil {
|
||||
// If we're locked onto a block, just choose that.
|
||||
block = cs.LockedBlock
|
||||
blockPartSet = cs.LockedBlockPartSet
|
||||
blockParts = cs.LockedBlockParts
|
||||
pol = cs.LockedPOL
|
||||
} else {
|
||||
var validation Validation
|
||||
@@ -276,26 +276,26 @@ func (cs *ConsensusState) RunActionPropose(height uint32, round uint16) {
|
||||
Txs: txs,
|
||||
},
|
||||
}
|
||||
blockPartSet = NewPartSetFromData(BinaryBytes(block))
|
||||
blockParts = NewPartSetFromData(BinaryBytes(block))
|
||||
pol = cs.LockedPOL // If exists, is a PoUnlock.
|
||||
}
|
||||
|
||||
if pol != nil {
|
||||
polPartSet = NewPartSetFromData(BinaryBytes(pol))
|
||||
polParts = NewPartSetFromData(BinaryBytes(pol))
|
||||
}
|
||||
|
||||
// Make proposal
|
||||
proposal := NewProposal(cs.Height, cs.Round,
|
||||
blockPartSet.Total(), blockPartSet.RootHash(),
|
||||
polPartSet.Total(), polPartSet.RootHash())
|
||||
blockParts.Total(), blockParts.RootHash(),
|
||||
polParts.Total(), polParts.RootHash())
|
||||
cs.PrivValidator.Sign(proposal)
|
||||
|
||||
// Set fields
|
||||
cs.Proposal = proposal
|
||||
cs.ProposalBlock = block
|
||||
cs.ProposalBlockPartSet = blockPartSet
|
||||
cs.ProposalBlockParts = blockParts
|
||||
cs.ProposalPOL = pol
|
||||
cs.ProposalPOLPartSet = polPartSet
|
||||
cs.ProposalPOLParts = polParts
|
||||
}
|
||||
|
||||
func (cs *ConsensusState) RunActionPrevote(height uint32, round uint16) *Vote {
|
||||
@@ -344,7 +344,7 @@ func (cs *ConsensusState) RunActionPrecommit(height uint32, round uint16) *Vote
|
||||
if len(hash) == 0 {
|
||||
// +2/3 prevoted nil. Just unlock.
|
||||
cs.LockedBlock = nil
|
||||
cs.LockedBlockPartSet = nil
|
||||
cs.LockedBlockParts = nil
|
||||
return nil
|
||||
} else if cs.ProposalBlock.HashesTo(hash) {
|
||||
// +2/3 prevoted for proposal block
|
||||
@@ -355,7 +355,7 @@ func (cs *ConsensusState) RunActionPrecommit(height uint32, round uint16) *Vote
|
||||
return nil
|
||||
}
|
||||
cs.LockedBlock = cs.ProposalBlock
|
||||
cs.LockedBlockPartSet = cs.ProposalBlockPartSet
|
||||
cs.LockedBlockParts = cs.ProposalBlockParts
|
||||
return cs.signAddVote(VoteTypePrecommit, hash)
|
||||
} else if cs.LockedBlock.HashesTo(hash) {
|
||||
// +2/3 prevoted for already locked block
|
||||
@@ -364,7 +364,7 @@ func (cs *ConsensusState) RunActionPrecommit(height uint32, round uint16) *Vote
|
||||
// We don't have the block that hashes to hash.
|
||||
// Unlock if we're locked.
|
||||
cs.LockedBlock = nil
|
||||
cs.LockedBlockPartSet = nil
|
||||
cs.LockedBlockParts = nil
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
@@ -396,13 +396,13 @@ func (cs *ConsensusState) RunActionCommit(height uint32, round uint16) *Vote {
|
||||
// TODO: Identify these strange cases.
|
||||
|
||||
var block *Block
|
||||
var blockPartSet *PartSet
|
||||
var blockParts *PartSet
|
||||
if cs.LockedBlock.HashesTo(hash) {
|
||||
block = cs.LockedBlock
|
||||
blockPartSet = cs.LockedBlockPartSet
|
||||
blockParts = cs.LockedBlockParts
|
||||
} else if cs.ProposalBlock.HashesTo(hash) {
|
||||
block = cs.ProposalBlock
|
||||
blockPartSet = cs.ProposalBlockPartSet
|
||||
blockParts = cs.ProposalBlockParts
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
@@ -416,7 +416,7 @@ func (cs *ConsensusState) RunActionCommit(height uint32, round uint16) *Vote {
|
||||
// Keep block in cs.Proposal*
|
||||
if !cs.ProposalBlock.HashesTo(hash) {
|
||||
cs.ProposalBlock = block
|
||||
cs.ProposalBlockPartSet = blockPartSet
|
||||
cs.ProposalBlockParts = blockParts
|
||||
}
|
||||
|
||||
// Save to blockStore
|
||||
@@ -457,6 +457,7 @@ func (cs *ConsensusState) RunActionFinalize(height uint32, round uint16) {
|
||||
}
|
||||
|
||||
// What was staged becomes committed.
|
||||
// XXX it's possible that this node never received the block to stage!!!
|
||||
cs.updateToState(cs.stagedState)
|
||||
}
|
||||
|
||||
@@ -482,8 +483,8 @@ func (cs *ConsensusState) SetProposal(proposal *Proposal) error {
|
||||
}
|
||||
|
||||
cs.Proposal = proposal
|
||||
cs.ProposalBlockPartSet = NewPartSetFromMetadata(proposal.BlockPartsTotal, proposal.BlockPartsHash)
|
||||
cs.ProposalPOLPartSet = NewPartSetFromMetadata(proposal.POLPartsTotal, proposal.POLPartsHash)
|
||||
cs.ProposalBlockParts = NewPartSetFromMetadata(proposal.BlockPartsTotal, proposal.BlockPartsHash)
|
||||
cs.ProposalPOLParts = NewPartSetFromMetadata(proposal.POLPartsTotal, proposal.POLPartsHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -498,18 +499,18 @@ func (cs *ConsensusState) AddProposalBlockPart(height uint32, round uint16, part
|
||||
}
|
||||
|
||||
// We're not expecting a block part.
|
||||
if cs.ProposalBlockPartSet != nil {
|
||||
if cs.ProposalBlockParts != nil {
|
||||
return false, nil // TODO: bad peer? Return error?
|
||||
}
|
||||
|
||||
added, err = cs.ProposalBlockPartSet.AddPart(part)
|
||||
added, err = cs.ProposalBlockParts.AddPart(part)
|
||||
if err != nil {
|
||||
return added, err
|
||||
}
|
||||
if added && cs.ProposalBlockPartSet.IsComplete() {
|
||||
if added && cs.ProposalBlockParts.IsComplete() {
|
||||
var n int64
|
||||
var err error
|
||||
cs.ProposalBlock = ReadBlock(cs.ProposalBlockPartSet.GetReader(), &n, &err)
|
||||
cs.ProposalBlock = ReadBlock(cs.ProposalBlockParts.GetReader(), &n, &err)
|
||||
return true, err
|
||||
}
|
||||
return true, nil
|
||||
@@ -525,18 +526,18 @@ func (cs *ConsensusState) AddProposalPOLPart(height uint32, round uint16, part *
|
||||
}
|
||||
|
||||
// We're not expecting a POL part.
|
||||
if cs.ProposalPOLPartSet != nil {
|
||||
if cs.ProposalPOLParts != nil {
|
||||
return false, nil // TODO: bad peer? Return error?
|
||||
}
|
||||
|
||||
added, err = cs.ProposalPOLPartSet.AddPart(part)
|
||||
added, err = cs.ProposalPOLParts.AddPart(part)
|
||||
if err != nil {
|
||||
return added, err
|
||||
}
|
||||
if added && cs.ProposalPOLPartSet.IsComplete() {
|
||||
if added && cs.ProposalPOLParts.IsComplete() {
|
||||
var n int64
|
||||
var err error
|
||||
cs.ProposalPOL = ReadPOL(cs.ProposalPOLPartSet.GetReader(), &n, &err)
|
||||
cs.ProposalPOL = ReadPOL(cs.ProposalPOLParts.GetReader(), &n, &err)
|
||||
return true, err
|
||||
}
|
||||
return true, nil
|
||||
|
||||
@@ -123,15 +123,15 @@ func TestRunActionPropose(t *testing.T) {
|
||||
cs.RunActionPropose(1, 0)
|
||||
rs := cs.GetRoundState()
|
||||
|
||||
// Check that Proposal, ProposalBlock, ProposalBlockPartSet are set.
|
||||
// Check that Proposal, ProposalBlock, ProposalBlockParts are set.
|
||||
if rs.Proposal == nil {
|
||||
t.Error("rs.Proposal should be set")
|
||||
}
|
||||
if rs.ProposalBlock == nil {
|
||||
t.Error("rs.ProposalBlock should be set")
|
||||
}
|
||||
if rs.ProposalBlockPartSet.Total() == 0 {
|
||||
t.Error("rs.ProposalBlockPartSet should be set")
|
||||
if rs.ProposalBlockParts.Total() == 0 {
|
||||
t.Error("rs.ProposalBlockParts should be set")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user