Skip to content

Commit a519825

Browse files
committedJun 19, 2018
consensus: fixes #1754
* updateToState exits early if the state isn't new, which happens after * fast syncing. This results in not sending a NewRoundStep message. The mempool * reactor depends on PeerState, which is updated by NewRoundStep * messages. If the peer never sends a NewRoundStep, the mempool reactor * will think they're behind, and never forward transactions. Note this * only happens when `create_empty_blocks = false`, because otherwise * peers will move through the consensus state and send a NewRoundStep * for a new step soon anyways. Simple fix is just to send the * NewRoundStep message during updateToState even if exit early
1 parent c84be3b commit a519825

File tree

4 files changed

+11
-6
lines changed

4 files changed

+11
-6
lines changed
 

‎consensus/state.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,12 @@ func (cs *ConsensusState) updateToState(state sm.State) {
460460

461461
// If state isn't further out than cs.state, just ignore.
462462
// This happens when SwitchToConsensus() is called in the reactor.
463-
// We don't want to reset e.g. the Votes.
463+
// We don't want to reset e.g. the Votes, but we still want to
464+
// signal the new round step, because other services (eg. mempool)
465+
// depend on having an up-to-date peer state!
464466
if !cs.state.IsEmpty() && (state.LastBlockHeight <= cs.state.LastBlockHeight) {
465467
cs.Logger.Info("Ignoring updateToState()", "newHeight", state.LastBlockHeight+1, "oldHeight", cs.state.LastBlockHeight+1)
468+
cs.newStep()
466469
return
467470
}
468471

@@ -492,6 +495,7 @@ func (cs *ConsensusState) updateToState(state sm.State) {
492495
} else {
493496
cs.StartTime = cs.config.Commit(cs.CommitTime)
494497
}
498+
495499
cs.Validators = validators
496500
cs.Proposal = nil
497501
cs.ProposalBlock = nil
@@ -517,7 +521,7 @@ func (cs *ConsensusState) newStep() {
517521
rs := cs.RoundStateEvent()
518522
cs.wal.Write(rs)
519523
cs.nSteps++
520-
// newStep is called by updateToStep in NewConsensusState before the eventBus is set!
524+
// newStep is called by updateToState in NewConsensusState before the eventBus is set!
521525
if cs.eventBus != nil {
522526
cs.eventBus.PublishEventNewRoundStep(rs)
523527
cs.evsw.FireEvent(types.EventNewRoundStep, &cs.RoundState)

‎mempool/mempool.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,11 +328,11 @@ func (mem *Mempool) notifyTxsAvailable() {
328328
panic("notified txs available but mempool is empty!")
329329
}
330330
if mem.txsAvailable != nil && !mem.notifiedTxsAvailable {
331+
// channel cap is 1, so this will send once
331332
select {
332333
case mem.txsAvailable <- mem.height + 1:
333334
default:
334335
}
335-
336336
mem.notifiedTxsAvailable = true
337337
}
338338
}

‎mempool/reactor.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ type PeerState interface {
103103
// Send new mempool txs to peer.
104104
func (memR *MempoolReactor) broadcastTxRoutine(peer p2p.Peer) {
105105
if !memR.config.Broadcast {
106+
memR.Logger.Info("Tx broadcasting is disabled")
106107
return
107108
}
108109

@@ -129,7 +130,8 @@ func (memR *MempoolReactor) broadcastTxRoutine(peer p2p.Peer) {
129130
height := memTx.Height()
130131
if peerState_i := peer.Get(types.PeerStateKey); peerState_i != nil {
131132
peerState := peerState_i.(PeerState)
132-
if peerState.GetHeight() < height-1 { // Allow for a lag of 1 block
133+
peerHeight := peerState.GetHeight()
134+
if peerHeight < height-1 { // Allow for a lag of 1 block
133135
time.Sleep(peerCatchupSleepIntervalMS * time.Millisecond)
134136
continue
135137
}

‎types/keys.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ package types
22

33
// UNSTABLE
44
var (
5-
PeerStateKey = "ConsensusReactor.peerState"
6-
PeerMempoolChKey = "MempoolReactor.peerMempoolCh"
5+
PeerStateKey = "ConsensusReactor.peerState"
76
)

0 commit comments

Comments
 (0)
Please sign in to comment.