mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-18 07:31:20 +00:00
BitArray sub fix
This commit is contained in:
@ -77,7 +77,7 @@ func ReadTx(r io.Reader, n *int64, err *error) Tx {
|
|||||||
type BaseTx struct {
|
type BaseTx struct {
|
||||||
Sequence uint
|
Sequence uint
|
||||||
Fee uint64
|
Fee uint64
|
||||||
Signature
|
Signature Signature
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadBaseTx(r io.Reader, n *int64, err *error) BaseTx {
|
func ReadBaseTx(r io.Reader, n *int64, err *error) BaseTx {
|
||||||
|
@ -56,16 +56,23 @@ func (bA BitArray) WriteTo(w io.Writer) (n int64, err error) {
|
|||||||
|
|
||||||
// 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 {
|
||||||
|
if i >= bA.bits {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return bA.elems[i/64]&uint64(1<<(i%64)) > 0
|
return bA.elems[i/64]&uint64(1<<(i%64)) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: behavior is undefined if i >= bA.bits
|
// NOTE: behavior is undefined if i >= bA.bits
|
||||||
func (bA BitArray) SetIndex(i uint, v bool) {
|
func (bA BitArray) SetIndex(i uint, v bool) bool {
|
||||||
|
if i >= bA.bits {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if v {
|
if v {
|
||||||
bA.elems[i/64] |= uint64(1 << (i % 64))
|
bA.elems[i/64] |= uint64(1 << (i % 64))
|
||||||
} else {
|
} else {
|
||||||
bA.elems[i/64] &= ^uint64(1 << (i % 64))
|
bA.elems[i/64] &= ^uint64(1 << (i % 64))
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) Copy() BitArray {
|
func (bA BitArray) Copy() BitArray {
|
||||||
@ -107,11 +114,28 @@ func (bA BitArray) Not() BitArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) Sub(o BitArray) BitArray {
|
func (bA BitArray) Sub(o BitArray) BitArray {
|
||||||
|
if bA.bits > o.bits {
|
||||||
|
c := bA.Copy()
|
||||||
|
for i := 0; i < len(o.elems)-1; i++ {
|
||||||
|
c.elems[i] &= ^c.elems[i]
|
||||||
|
}
|
||||||
|
i := uint(len(o.elems) - 1)
|
||||||
|
if i >= 0 {
|
||||||
|
for idx := i * 64; idx < o.bits; idx++ {
|
||||||
|
c.SetIndex(idx, c.GetIndex(idx) && !o.GetIndex(idx))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
} else {
|
||||||
return bA.And(o.Not())
|
return bA.And(o.Not())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bA BitArray) PickRandom() (int, bool) {
|
func (bA BitArray) PickRandom() (int, bool) {
|
||||||
length := len(bA.elems)
|
length := len(bA.elems)
|
||||||
|
if length == 0 {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
randElemStart := rand.Intn(length)
|
randElemStart := rand.Intn(length)
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
elemIdx := ((i + randElemStart) % length)
|
elemIdx := ((i + randElemStart) % length)
|
||||||
|
@ -111,17 +111,17 @@ func TestOr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSub(t *testing.T) {
|
func TestSub1(t *testing.T) {
|
||||||
|
|
||||||
bA1, _ := randBitArray(31)
|
bA1, _ := randBitArray(31)
|
||||||
bA2, _ := randBitArray(51)
|
bA2, _ := randBitArray(51)
|
||||||
bA3 := bA1.Sub(bA2)
|
bA3 := bA1.Sub(bA2)
|
||||||
|
|
||||||
if bA3.bits != 31 {
|
if bA3.bits != bA1.bits {
|
||||||
t.Error("Expected min bits")
|
t.Error("Expected bA1 bits")
|
||||||
}
|
}
|
||||||
if len(bA3.elems) != len(bA1.elems) {
|
if len(bA3.elems) != len(bA1.elems) {
|
||||||
t.Error("Expected min elems length")
|
t.Error("Expected bA1 elems length")
|
||||||
}
|
}
|
||||||
for i := uint(0); i < bA3.bits; i++ {
|
for i := uint(0); i < bA3.bits; i++ {
|
||||||
expected := bA1.GetIndex(i)
|
expected := bA1.GetIndex(i)
|
||||||
@ -133,3 +133,26 @@ func TestSub(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSub2(t *testing.T) {
|
||||||
|
|
||||||
|
bA1, _ := randBitArray(51)
|
||||||
|
bA2, _ := randBitArray(31)
|
||||||
|
bA3 := bA1.Sub(bA2)
|
||||||
|
|
||||||
|
if bA3.bits != bA1.bits {
|
||||||
|
t.Error("Expected bA1 bits")
|
||||||
|
}
|
||||||
|
if len(bA3.elems) != len(bA1.elems) {
|
||||||
|
t.Error("Expected bA1 elems length")
|
||||||
|
}
|
||||||
|
for i := uint(0); i < bA3.bits; i++ {
|
||||||
|
expected := bA1.GetIndex(i)
|
||||||
|
if i < bA2.bits && bA2.GetIndex(i) {
|
||||||
|
expected = false
|
||||||
|
}
|
||||||
|
if bA3.GetIndex(i) != expected {
|
||||||
|
t.Error("Wrong bit from bA3")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ package consensus
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
. "github.com/tendermint/tendermint/binary"
|
. "github.com/tendermint/tendermint/binary"
|
||||||
@ -20,7 +21,7 @@ type Proposal struct {
|
|||||||
BlockPartsHash []byte
|
BlockPartsHash []byte
|
||||||
POLPartsTotal uint16
|
POLPartsTotal uint16
|
||||||
POLPartsHash []byte
|
POLPartsHash []byte
|
||||||
Signature
|
Signature Signature
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProposal(height uint32, round uint16,
|
func NewProposal(height uint32, round uint16,
|
||||||
@ -67,3 +68,10 @@ func (p *Proposal) GetSignature() Signature {
|
|||||||
func (p *Proposal) SetSignature(sig Signature) {
|
func (p *Proposal) SetSignature(sig Signature) {
|
||||||
p.Signature = sig
|
p.Signature = sig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Proposal) String() string {
|
||||||
|
return fmt.Sprintf("Proposal{%v/%v %X/%v %X/%v %v}", p.Height, p.Round,
|
||||||
|
p.BlockPartsHash, p.BlockPartsTotal,
|
||||||
|
p.POLPartsHash, p.POLPartsTotal,
|
||||||
|
p.Signature)
|
||||||
|
}
|
||||||
|
@ -183,6 +183,8 @@ func (conR *ConsensusReactor) Receive(chId byte, peer *p2p.Peer, msgBytes []byte
|
|||||||
voteAddCounter := 0
|
voteAddCounter := 0
|
||||||
var err error = nil
|
var err error = nil
|
||||||
|
|
||||||
|
log.Debug("[%X][%v] Receive: %v", chId, peer, msg_)
|
||||||
|
|
||||||
switch chId {
|
switch chId {
|
||||||
case StateCh:
|
case StateCh:
|
||||||
switch msg_.(type) {
|
switch msg_.(type) {
|
||||||
@ -354,6 +356,7 @@ ACTION_LOOP:
|
|||||||
Height: height,
|
Height: height,
|
||||||
Round: round,
|
Round: round,
|
||||||
Step: step,
|
Step: step,
|
||||||
|
NumValidators: uint32(rs.Validators.Size()),
|
||||||
SecondsSinceStartTime: uint32(rs.RoundElapsed().Seconds()),
|
SecondsSinceStartTime: uint32(rs.RoundElapsed().Seconds()),
|
||||||
}
|
}
|
||||||
conR.sw.Broadcast(StateCh, msg)
|
conR.sw.Broadcast(StateCh, msg)
|
||||||
@ -512,6 +515,7 @@ OUTER_LOOP:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send proposal POL part?
|
// Send proposal POL part?
|
||||||
|
if rs.ProposalPOLPartSet != nil {
|
||||||
if index, ok := rs.ProposalPOLPartSet.BitArray().Sub(
|
if index, ok := rs.ProposalPOLPartSet.BitArray().Sub(
|
||||||
prs.ProposalPOLBitArray).PickRandom(); ok {
|
prs.ProposalPOLBitArray).PickRandom(); ok {
|
||||||
msg := &PartMessage{
|
msg := &PartMessage{
|
||||||
@ -524,6 +528,7 @@ OUTER_LOOP:
|
|||||||
ps.SetHasProposalPOLPart(rs.Height, rs.Round, uint16(index))
|
ps.SetHasProposalPOLPart(rs.Height, rs.Round, uint16(index))
|
||||||
continue OUTER_LOOP
|
continue OUTER_LOOP
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Nothing to do. Sleep.
|
// Nothing to do. Sleep.
|
||||||
time.Sleep(peerGossipSleepDuration)
|
time.Sleep(peerGossipSleepDuration)
|
||||||
@ -708,15 +713,17 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) error {
|
|||||||
ps.StartTime = startTime
|
ps.StartTime = startTime
|
||||||
|
|
||||||
// Reset the rest
|
// Reset the rest
|
||||||
|
if ps.Round != msg.Round {
|
||||||
ps.Proposal = false
|
ps.Proposal = false
|
||||||
ps.ProposalBlockHash = nil
|
ps.ProposalBlockHash = nil
|
||||||
ps.ProposalBlockBitArray = BitArray{}
|
ps.ProposalBlockBitArray = BitArray{}
|
||||||
ps.ProposalPOLHash = nil
|
ps.ProposalPOLHash = nil
|
||||||
ps.ProposalPOLBitArray = BitArray{}
|
ps.ProposalPOLBitArray = BitArray{}
|
||||||
ps.Prevotes = BitArray{}
|
ps.Prevotes = NewBitArray(uint(msg.NumValidators))
|
||||||
ps.Precommits = BitArray{}
|
ps.Precommits = NewBitArray(uint(msg.NumValidators))
|
||||||
|
}
|
||||||
if ps.Height != msg.Height {
|
if ps.Height != msg.Height {
|
||||||
ps.Commits = BitArray{}
|
ps.Commits = NewBitArray(uint(msg.NumValidators))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -782,6 +789,7 @@ type NewRoundStepMessage struct {
|
|||||||
Height uint32
|
Height uint32
|
||||||
Round uint16
|
Round uint16
|
||||||
Step RoundStep
|
Step RoundStep
|
||||||
|
NumValidators uint32
|
||||||
SecondsSinceStartTime uint32
|
SecondsSinceStartTime uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,6 +798,7 @@ func readNewRoundStepMessage(r io.Reader, n *int64, err *error) *NewRoundStepMes
|
|||||||
Height: ReadUInt32(r, n, err),
|
Height: ReadUInt32(r, n, err),
|
||||||
Round: ReadUInt16(r, n, err),
|
Round: ReadUInt16(r, n, err),
|
||||||
Step: RoundStep(ReadUInt8(r, n, err)),
|
Step: RoundStep(ReadUInt8(r, n, err)),
|
||||||
|
NumValidators: ReadUInt32(r, n, err),
|
||||||
SecondsSinceStartTime: ReadUInt32(r, n, err),
|
SecondsSinceStartTime: ReadUInt32(r, n, err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -799,6 +808,7 @@ func (m *NewRoundStepMessage) WriteTo(w io.Writer) (n int64, err error) {
|
|||||||
WriteUInt32(w, m.Height, &n, &err)
|
WriteUInt32(w, m.Height, &n, &err)
|
||||||
WriteUInt16(w, m.Round, &n, &err)
|
WriteUInt16(w, m.Round, &n, &err)
|
||||||
WriteUInt8(w, uint8(m.Step), &n, &err)
|
WriteUInt8(w, uint8(m.Step), &n, &err)
|
||||||
|
WriteUInt32(w, m.NumValidators, &n, &err)
|
||||||
WriteUInt32(w, m.SecondsSinceStartTime, &n, &err)
|
WriteUInt32(w, m.SecondsSinceStartTime, &n, &err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ func (c *MConnection) Stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *MConnection) String() string {
|
func (c *MConnection) String() string {
|
||||||
return fmt.Sprintf("/%v/", c.conn.RemoteAddr())
|
return fmt.Sprintf("MConn{%v}", c.conn.RemoteAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MConnection) flush() {
|
func (c *MConnection) flush() {
|
||||||
@ -163,6 +163,8 @@ func (c *MConnection) Send(chId byte, msg Binary) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug("[%X][%v] Send: %v", chId, c, msg)
|
||||||
|
|
||||||
// Send message to channel.
|
// Send message to channel.
|
||||||
channel, ok := c.channelsIdx[chId]
|
channel, ok := c.channelsIdx[chId]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -188,6 +190,8 @@ func (c *MConnection) TrySend(chId byte, msg Binary) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug("[%X][%v] TrySend: %v", chId, c, msg)
|
||||||
|
|
||||||
// Send message to channel.
|
// Send message to channel.
|
||||||
channel, ok := c.channelsIdx[chId]
|
channel, ok := c.channelsIdx[chId]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -312,7 +316,7 @@ func (c *MConnection) sendPacket() bool {
|
|||||||
if leastChannel == nil {
|
if leastChannel == nil {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
log.Debug("Found a packet to send")
|
// log.Debug("Found a packet to send")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make & send a packet from this channel
|
// Make & send a packet from this channel
|
||||||
@ -553,7 +557,7 @@ func (p packet) WriteTo(w io.Writer) (n int64, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p packet) String() string {
|
func (p packet) String() string {
|
||||||
return fmt.Sprintf("%X:%X", p.ChannelId, p.Bytes)
|
return fmt.Sprintf("Packet{%X:%X}", p.ChannelId, p.Bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readPacketSafe(r io.Reader) (pkt packet, n int64, err error) {
|
func readPacketSafe(r io.Reader) (pkt packet, n int64, err error) {
|
||||||
@ -580,7 +584,7 @@ func (tm TypedMessage) WriteTo(w io.Writer) (n int64, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tm TypedMessage) String() string {
|
func (tm TypedMessage) String() string {
|
||||||
return fmt.Sprintf("<%X:%v>", tm.Type, tm.Msg)
|
return fmt.Sprintf("TMsg{%X:%v}", tm.Type, tm.Msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tm TypedMessage) Bytes() []byte {
|
func (tm TypedMessage) Bytes() []byte {
|
||||||
|
@ -100,9 +100,9 @@ func (p *Peer) WriteTo(w io.Writer) (n int64, err error) {
|
|||||||
|
|
||||||
func (p *Peer) String() string {
|
func (p *Peer) String() string {
|
||||||
if p.outbound {
|
if p.outbound {
|
||||||
return fmt.Sprintf("P(->%v)", p.mconn)
|
return fmt.Sprintf("Peer{->%v}", p.mconn)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("P(%v->)", p.mconn)
|
return fmt.Sprintf("Peer{%v->}", p.mconn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ func (sw *Switch) Broadcast(chId byte, msg Binary) (numSuccess, numFailure int)
|
|||||||
log.Debug("[%X] Broadcast: %v", chId, msg)
|
log.Debug("[%X] Broadcast: %v", chId, msg)
|
||||||
for _, peer := range sw.peers.List() {
|
for _, peer := range sw.peers.List() {
|
||||||
success := peer.TrySend(chId, msg)
|
success := peer.TrySend(chId, msg)
|
||||||
log.Debug("Broadcast for peer %v success: %v", peer, success)
|
// log.Debug("Broadcast for peer %v success: %v", peer, success)
|
||||||
if success {
|
if success {
|
||||||
numSuccess += 1
|
numSuccess += 1
|
||||||
} else {
|
} else {
|
||||||
|
@ -35,11 +35,12 @@ func NewNode() *Node {
|
|||||||
state := state_.LoadState(stateDB)
|
state := state_.LoadState(stateDB)
|
||||||
if state == nil {
|
if state == nil {
|
||||||
state = state_.GenesisStateFromFile(stateDB, config.RootDir+"/genesis.json")
|
state = state_.GenesisStateFromFile(stateDB, config.RootDir+"/genesis.json")
|
||||||
|
state.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get PrivAccount
|
// Get PrivAccount
|
||||||
var privValidator *consensus.PrivValidator
|
var privValidator *consensus.PrivValidator
|
||||||
if _, err := os.Stat(config.RootDir + "/private.json"); os.IsExist(err) {
|
if _, err := os.Stat(config.RootDir + "/private.json"); err == nil {
|
||||||
privAccount := state_.PrivAccountFromFile(config.RootDir + "/private.json")
|
privAccount := state_.PrivAccountFromFile(config.RootDir + "/private.json")
|
||||||
privValidatorDB := db_.NewMemDB() // TODO configurable db.
|
privValidatorDB := db_.NewMemDB() // TODO configurable db.
|
||||||
privValidator = consensus.NewPrivValidator(privValidatorDB, privAccount)
|
privValidator = consensus.NewPrivValidator(privValidatorDB, privAccount)
|
||||||
|
Reference in New Issue
Block a user