mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-16 06:41:19 +00:00
BitArray takes a pointer receiver. More logging
This commit is contained in:
@ -13,30 +13,26 @@ type BitArray struct {
|
|||||||
Elems []uint64 // NOTE: persisted via reflect, must be exported
|
Elems []uint64 // NOTE: persisted via reflect, must be exported
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBitArray(bits uint) BitArray {
|
func NewBitArray(bits uint) *BitArray {
|
||||||
return BitArray{
|
return &BitArray{
|
||||||
Bits: bits,
|
Bits: bits,
|
||||||
Elems: make([]uint64, (bits+63)/64),
|
Elems: make([]uint64, (bits+63)/64),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) Size() uint {
|
func (bA *BitArray) Size() uint {
|
||||||
return bA.Bits
|
return bA.Bits
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) IsZero() bool {
|
|
||||||
return bA.Bits == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: behavior is undefined if i >= bA.Bits
|
// NOTE: behavior is undefined if i >= bA.Bits
|
||||||
func (bA BitArray) GetIndex(i uint) bool {
|
func (bA *BitArray) GetIndex(i uint) bool {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
return bA.getIndex(i)
|
return bA.getIndex(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) getIndex(i uint) bool {
|
func (bA *BitArray) getIndex(i uint) bool {
|
||||||
if i >= bA.Bits {
|
if i >= bA.Bits {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -44,15 +40,14 @@ func (bA BitArray) getIndex(i uint) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: behavior is undefined if i >= bA.Bits
|
// NOTE: behavior is undefined if i >= bA.Bits
|
||||||
func (bA BitArray) SetIndex(i uint, v bool) bool {
|
func (bA *BitArray) SetIndex(i uint, v bool) bool {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
return bA.setIndex(i, v)
|
return bA.setIndex(i, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) setIndex(i uint, v bool) bool {
|
func (bA *BitArray) setIndex(i uint, v bool) bool {
|
||||||
|
|
||||||
if i >= bA.Bits {
|
if i >= bA.Bits {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -64,32 +59,32 @@ func (bA BitArray) setIndex(i uint, v bool) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) Copy() BitArray {
|
func (bA *BitArray) Copy() *BitArray {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
return bA.copy()
|
return bA.copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) copy() BitArray {
|
func (bA *BitArray) copy() *BitArray {
|
||||||
c := make([]uint64, len(bA.Elems))
|
c := make([]uint64, len(bA.Elems))
|
||||||
copy(c, bA.Elems)
|
copy(c, bA.Elems)
|
||||||
return BitArray{
|
return &BitArray{
|
||||||
Bits: bA.Bits,
|
Bits: bA.Bits,
|
||||||
Elems: c,
|
Elems: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) copyBits(bits uint) BitArray {
|
func (bA *BitArray) copyBits(bits uint) *BitArray {
|
||||||
c := make([]uint64, (bits+63)/64)
|
c := make([]uint64, (bits+63)/64)
|
||||||
copy(c, bA.Elems)
|
copy(c, bA.Elems)
|
||||||
return BitArray{
|
return &BitArray{
|
||||||
Bits: bits,
|
Bits: bits,
|
||||||
Elems: c,
|
Elems: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a BitArray of larger bits size.
|
// Returns a BitArray of larger bits size.
|
||||||
func (bA BitArray) Or(o BitArray) BitArray {
|
func (bA *BitArray) Or(o *BitArray) *BitArray {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
@ -101,14 +96,14 @@ func (bA BitArray) Or(o BitArray) BitArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a BitArray of smaller bit size.
|
// Returns a BitArray of smaller bit size.
|
||||||
func (bA BitArray) And(o BitArray) BitArray {
|
func (bA *BitArray) And(o *BitArray) *BitArray {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
return bA.and(o)
|
return bA.and(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) and(o BitArray) BitArray {
|
func (bA *BitArray) and(o *BitArray) *BitArray {
|
||||||
c := bA.copyBits(MinUint(bA.Bits, o.Bits))
|
c := bA.copyBits(MinUint(bA.Bits, o.Bits))
|
||||||
for i := 0; i < len(c.Elems); i++ {
|
for i := 0; i < len(c.Elems); i++ {
|
||||||
c.Elems[i] &= o.Elems[i]
|
c.Elems[i] &= o.Elems[i]
|
||||||
@ -116,7 +111,7 @@ func (bA BitArray) and(o BitArray) BitArray {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) Not() BitArray {
|
func (bA *BitArray) Not() *BitArray {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
@ -127,7 +122,7 @@ func (bA BitArray) Not() BitArray {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) Sub(o BitArray) BitArray {
|
func (bA *BitArray) Sub(o *BitArray) *BitArray {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
@ -148,7 +143,7 @@ func (bA BitArray) Sub(o BitArray) BitArray {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) IsFull() bool {
|
func (bA *BitArray) IsFull() bool {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
@ -169,7 +164,7 @@ func (bA BitArray) IsFull() bool {
|
|||||||
return (lastElem+1)&((uint64(1)<<lastElemBits)-1) == 0
|
return (lastElem+1)&((uint64(1)<<lastElemBits)-1) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) PickRandom() (uint, bool) {
|
func (bA *BitArray) PickRandom() (uint, bool) {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
@ -209,20 +204,23 @@ func (bA BitArray) PickRandom() (uint, bool) {
|
|||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) String() string {
|
func (bA *BitArray) String() string {
|
||||||
|
if bA == nil {
|
||||||
|
return "nil-BitArray"
|
||||||
|
}
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
|
|
||||||
return bA.stringIndented("")
|
return bA.stringIndented("")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) StringIndented(indent string) string {
|
func (bA *BitArray) StringIndented(indent string) string {
|
||||||
bA.mtx.Lock()
|
bA.mtx.Lock()
|
||||||
defer bA.mtx.Unlock()
|
defer bA.mtx.Unlock()
|
||||||
return bA.StringIndented(indent)
|
return bA.StringIndented(indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) stringIndented(indent string) string {
|
func (bA *BitArray) stringIndented(indent string) string {
|
||||||
|
|
||||||
lines := []string{}
|
lines := []string{}
|
||||||
bits := ""
|
bits := ""
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func randBitArray(bits uint) (BitArray, []byte) {
|
func randBitArray(bits uint) (*BitArray, []byte) {
|
||||||
src := RandBytes(int((bits + 7) / 8))
|
src := RandBytes(int((bits + 7) / 8))
|
||||||
bA := NewBitArray(bits)
|
bA := NewBitArray(bits)
|
||||||
for i := uint(0); i < uint(len(src)); i++ {
|
for i := uint(0); i < uint(len(src)); i++ {
|
||||||
|
@ -442,7 +442,7 @@ OUTER_LOOP:
|
|||||||
sleeping = 0
|
sleeping = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
trySendVote := func(voteSet *VoteSet, peerVoteSet BitArray) (sent bool) {
|
trySendVote := func(voteSet *VoteSet, peerVoteSet *BitArray) (sent bool) {
|
||||||
if prs.Height == voteSet.Height() {
|
if prs.Height == voteSet.Height() {
|
||||||
// Initialize Prevotes/Precommits/Commits if needed
|
// Initialize Prevotes/Precommits/Commits if needed
|
||||||
ps.EnsureVoteBitArrays(prs.Height, voteSet.Size())
|
ps.EnsureVoteBitArrays(prs.Height, voteSet.Size())
|
||||||
@ -460,7 +460,7 @@ OUTER_LOOP:
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
trySendCommitFromValidation := func(blockMeta *types.BlockMeta, validation *types.Validation, peerVoteSet BitArray) (sent bool) {
|
trySendCommitFromValidation := func(blockMeta *types.BlockMeta, validation *types.Validation, peerVoteSet *BitArray) (sent bool) {
|
||||||
// Initialize Commits if needed
|
// Initialize Commits if needed
|
||||||
ps.EnsureVoteBitArrays(prs.Height, uint(len(validation.Commits)))
|
ps.EnsureVoteBitArrays(prs.Height, uint(len(validation.Commits)))
|
||||||
|
|
||||||
@ -588,13 +588,13 @@ type PeerRoundState struct {
|
|||||||
StartTime time.Time // Estimated start of round 0 at this height
|
StartTime time.Time // Estimated start of round 0 at this height
|
||||||
Proposal bool // True if peer has proposal for this round
|
Proposal bool // True if peer has proposal for this round
|
||||||
ProposalBlockParts types.PartSetHeader //
|
ProposalBlockParts types.PartSetHeader //
|
||||||
ProposalBlockBitArray BitArray // True bit -> has part
|
ProposalBlockBitArray *BitArray // True bit -> has part
|
||||||
ProposalPOLParts types.PartSetHeader //
|
ProposalPOLParts types.PartSetHeader //
|
||||||
ProposalPOLBitArray BitArray // True bit -> has part
|
ProposalPOLBitArray *BitArray // True bit -> has part
|
||||||
Prevotes BitArray // All votes peer has for this round
|
Prevotes *BitArray // All votes peer has for this round
|
||||||
Precommits BitArray // All precommits peer has for this round
|
Precommits *BitArray // All precommits peer has for this round
|
||||||
Commits BitArray // All commits peer has for this height
|
Commits *BitArray // All commits peer has for this height
|
||||||
LastCommits BitArray // All commits peer has for last height
|
LastCommits *BitArray // All commits peer has for last height
|
||||||
HasAllCatchupCommits bool // Used for catch-up
|
HasAllCatchupCommits bool // Used for catch-up
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,12 +606,14 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type PeerState struct {
|
type PeerState struct {
|
||||||
|
Key string
|
||||||
|
|
||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
PeerRoundState
|
PeerRoundState
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPeerState(peer *p2p.Peer) *PeerState {
|
func NewPeerState(peer *p2p.Peer) *PeerState {
|
||||||
return &PeerState{}
|
return &PeerState{Key: peer.Key}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an atomic snapshot of the PeerRoundState.
|
// Returns an atomic snapshot of the PeerRoundState.
|
||||||
@ -672,13 +674,13 @@ func (ps *PeerState) EnsureVoteBitArrays(height uint, numValidators uint) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ps.Prevotes.IsZero() {
|
if ps.Prevotes == nil {
|
||||||
ps.Prevotes = NewBitArray(numValidators)
|
ps.Prevotes = NewBitArray(numValidators)
|
||||||
}
|
}
|
||||||
if ps.Precommits.IsZero() {
|
if ps.Precommits == nil {
|
||||||
ps.Precommits = NewBitArray(numValidators)
|
ps.Precommits = NewBitArray(numValidators)
|
||||||
}
|
}
|
||||||
if ps.Commits.IsZero() {
|
if ps.Commits == nil {
|
||||||
ps.Commits = NewBitArray(numValidators)
|
ps.Commits = NewBitArray(numValidators)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -694,6 +696,7 @@ func (ps *PeerState) setHasVote(height uint, round uint, type_ byte, index uint)
|
|||||||
if ps.Height == height+1 && type_ == types.VoteTypeCommit {
|
if ps.Height == height+1 && type_ == types.VoteTypeCommit {
|
||||||
// Special case for LastCommits.
|
// Special case for LastCommits.
|
||||||
ps.LastCommits.SetIndex(index, true)
|
ps.LastCommits.SetIndex(index, true)
|
||||||
|
log.Debug("SetHasVote", "lastCommits", ps.LastCommits, "index", index)
|
||||||
return
|
return
|
||||||
} else if ps.Height != height {
|
} else if ps.Height != height {
|
||||||
// Does not apply.
|
// Does not apply.
|
||||||
@ -703,14 +706,17 @@ func (ps *PeerState) setHasVote(height uint, round uint, type_ byte, index uint)
|
|||||||
switch type_ {
|
switch type_ {
|
||||||
case types.VoteTypePrevote:
|
case types.VoteTypePrevote:
|
||||||
ps.Prevotes.SetIndex(index, true)
|
ps.Prevotes.SetIndex(index, true)
|
||||||
|
log.Debug("SetHasVote", "peer", ps.Key, "prevotes", ps.Prevotes, "index", index)
|
||||||
case types.VoteTypePrecommit:
|
case types.VoteTypePrecommit:
|
||||||
ps.Precommits.SetIndex(index, true)
|
ps.Precommits.SetIndex(index, true)
|
||||||
|
log.Debug("SetHasVote", "peer", ps.Key, "precommits", ps.Precommits, "index", index)
|
||||||
case types.VoteTypeCommit:
|
case types.VoteTypeCommit:
|
||||||
if round < ps.Round {
|
if round < ps.Round {
|
||||||
ps.Prevotes.SetIndex(index, true)
|
ps.Prevotes.SetIndex(index, true)
|
||||||
ps.Precommits.SetIndex(index, true)
|
ps.Precommits.SetIndex(index, true)
|
||||||
}
|
}
|
||||||
ps.Commits.SetIndex(index, true)
|
ps.Commits.SetIndex(index, true)
|
||||||
|
log.Debug("SetHasVote", "peer", ps.Key, "commits", ps.Commits, "index", index)
|
||||||
default:
|
default:
|
||||||
panic("Invalid vote type")
|
panic("Invalid vote type")
|
||||||
}
|
}
|
||||||
@ -744,22 +750,22 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage, rs *Roun
|
|||||||
if psHeight != msg.Height || psRound != msg.Round {
|
if psHeight != msg.Height || psRound != msg.Round {
|
||||||
ps.Proposal = false
|
ps.Proposal = false
|
||||||
ps.ProposalBlockParts = types.PartSetHeader{}
|
ps.ProposalBlockParts = types.PartSetHeader{}
|
||||||
ps.ProposalBlockBitArray = BitArray{}
|
ps.ProposalBlockBitArray = nil
|
||||||
ps.ProposalPOLParts = types.PartSetHeader{}
|
ps.ProposalPOLParts = types.PartSetHeader{}
|
||||||
ps.ProposalPOLBitArray = BitArray{}
|
ps.ProposalPOLBitArray = nil
|
||||||
// We'll update the BitArray capacity later.
|
// We'll update the BitArray capacity later.
|
||||||
ps.Prevotes = BitArray{}
|
ps.Prevotes = nil
|
||||||
ps.Precommits = BitArray{}
|
ps.Precommits = nil
|
||||||
}
|
}
|
||||||
if psHeight != msg.Height {
|
if psHeight != msg.Height {
|
||||||
// Shift Commits to LastCommits
|
// Shift Commits to LastCommits
|
||||||
if psHeight+1 == msg.Height {
|
if psHeight+1 == msg.Height {
|
||||||
ps.LastCommits = ps.Commits
|
ps.LastCommits = ps.Commits
|
||||||
} else {
|
} else {
|
||||||
ps.LastCommits = BitArray{}
|
ps.LastCommits = nil
|
||||||
}
|
}
|
||||||
// We'll update the BitArray capacity later.
|
// We'll update the BitArray capacity later.
|
||||||
ps.Commits = BitArray{}
|
ps.Commits = nil
|
||||||
ps.HasAllCatchupCommits = false
|
ps.HasAllCatchupCommits = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -842,7 +848,7 @@ func (m *NewRoundStepMessage) String() string {
|
|||||||
type CommitStepMessage struct {
|
type CommitStepMessage struct {
|
||||||
Height uint
|
Height uint
|
||||||
BlockParts types.PartSetHeader
|
BlockParts types.PartSetHeader
|
||||||
BlockBitArray BitArray
|
BlockBitArray *BitArray
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CommitStepMessage) String() string {
|
func (m *CommitStepMessage) String() string {
|
||||||
|
@ -26,7 +26,7 @@ type VoteSet struct {
|
|||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
valSet *sm.ValidatorSet
|
valSet *sm.ValidatorSet
|
||||||
votes []*types.Vote // validator index -> vote
|
votes []*types.Vote // validator index -> vote
|
||||||
votesBitArray BitArray // validator index -> has vote?
|
votesBitArray *BitArray // validator index -> has vote?
|
||||||
votesByBlock map[string]uint64 // string(blockHash)+string(blockParts) -> vote sum.
|
votesByBlock map[string]uint64 // string(blockHash)+string(blockParts) -> vote sum.
|
||||||
totalVotes uint64
|
totalVotes uint64
|
||||||
maj23Hash []byte
|
maj23Hash []byte
|
||||||
@ -148,9 +148,9 @@ func (voteSet *VoteSet) AddFromCommits(commits *VoteSet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (voteSet *VoteSet) BitArray() BitArray {
|
func (voteSet *VoteSet) BitArray() *BitArray {
|
||||||
if voteSet == nil {
|
if voteSet == nil {
|
||||||
return BitArray{}
|
return nil
|
||||||
}
|
}
|
||||||
voteSet.mtx.Lock()
|
voteSet.mtx.Lock()
|
||||||
defer voteSet.mtx.Unlock()
|
defer voteSet.mtx.Unlock()
|
||||||
|
@ -201,7 +201,7 @@ type Validation struct {
|
|||||||
|
|
||||||
// Volatile
|
// Volatile
|
||||||
hash []byte
|
hash []byte
|
||||||
bitArray BitArray
|
bitArray *BitArray
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Validation) ValidateBasic() error {
|
func (v *Validation) ValidateBasic() error {
|
||||||
@ -254,8 +254,8 @@ func (v *Validation) StringIndented(indent string) string {
|
|||||||
indent, v.hash)
|
indent, v.hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Validation) BitArray() BitArray {
|
func (v *Validation) BitArray() *BitArray {
|
||||||
if v.bitArray.IsZero() {
|
if v.bitArray == nil {
|
||||||
v.bitArray = NewBitArray(uint(len(v.Commits)))
|
v.bitArray = NewBitArray(uint(len(v.Commits)))
|
||||||
for i, commit := range v.Commits {
|
for i, commit := range v.Commits {
|
||||||
v.bitArray.SetIndex(uint(i), !commit.IsZero())
|
v.bitArray.SetIndex(uint(i), !commit.IsZero())
|
||||||
|
@ -97,7 +97,7 @@ type PartSet struct {
|
|||||||
|
|
||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
parts []*Part
|
parts []*Part
|
||||||
partsBitArray BitArray
|
partsBitArray *BitArray
|
||||||
count uint
|
count uint
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ func (ps *PartSet) HasHeader(header PartSetHeader) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *PartSet) BitArray() BitArray {
|
func (ps *PartSet) BitArray() *BitArray {
|
||||||
ps.mtx.Lock()
|
ps.mtx.Lock()
|
||||||
defer ps.mtx.Unlock()
|
defer ps.mtx.Unlock()
|
||||||
return ps.partsBitArray.Copy()
|
return ps.partsBitArray.Copy()
|
||||||
|
Reference in New Issue
Block a user