mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-29 14:11:21 +00:00
small fixes to adr, comments and cleanup
This commit is contained in:
parent
299a7f3c0a
commit
714ac4fc46
@ -17,7 +17,7 @@ var (
|
|||||||
peerTimeout = 15 * time.Second // not const so we can override with tests
|
peerTimeout = 15 * time.Second // not const so we can override with tests
|
||||||
|
|
||||||
// Minimum recv rate to ensure we're receiving blocks from a peer fast
|
// Minimum recv rate to ensure we're receiving blocks from a peer fast
|
||||||
// enough. If a peer is not sending us data at at least that rate, we
|
// enough. If a peer is not sending data at at least that rate, we
|
||||||
// consider them to have timedout and we disconnect.
|
// consider them to have timedout and we disconnect.
|
||||||
//
|
//
|
||||||
// Assuming a DSL connection (not a good choice) 128 Kbps (upload) ~ 15 KB/s,
|
// Assuming a DSL connection (not a good choice) 128 Kbps (upload) ~ 15 KB/s,
|
||||||
|
@ -83,23 +83,26 @@ func (pool *blockPool) rescheduleRequest(peerID p2p.ID, height int64) {
|
|||||||
|
|
||||||
// Updates the pool's max height. If no peers are left maxPeerHeight is set to 0.
|
// Updates the pool's max height. If no peers are left maxPeerHeight is set to 0.
|
||||||
func (pool *blockPool) updateMaxPeerHeight() {
|
func (pool *blockPool) updateMaxPeerHeight() {
|
||||||
var max int64
|
var newMax int64
|
||||||
for _, peer := range pool.peers {
|
for _, peer := range pool.peers {
|
||||||
if peer.height > max {
|
if peer.height > newMax {
|
||||||
max = peer.height
|
newMax = peer.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if max < pool.maxPeerHeight {
|
if newMax < pool.maxPeerHeight {
|
||||||
// Remove any planned requests for heights over the new maxPeerHeight
|
// Remove any planned requests for heights over the new maxPeerHeight.
|
||||||
|
// This may happen if a peer has updated with lower height.
|
||||||
for h := range pool.requests {
|
for h := range pool.requests {
|
||||||
if h > max {
|
if h > newMax {
|
||||||
delete(pool.requests, h)
|
delete(pool.requests, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if pool.nextRequestHeight > newMax {
|
||||||
pool.maxPeerHeight = max
|
pool.nextRequestHeight = newMax + 1
|
||||||
|
}
|
||||||
|
pool.maxPeerHeight = newMax
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a new peer or updates an existing peer with a new height.
|
// Adds a new peer or updates an existing peer with a new height.
|
||||||
|
@ -240,7 +240,7 @@ func (bcR *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case *bcBlockResponseMessage:
|
case *bcBlockResponseMessage:
|
||||||
msgData := bcReactorMessage{
|
msgForFSM := bcReactorMessage{
|
||||||
event: blockResponseEv,
|
event: blockResponseEv,
|
||||||
data: bReactorEventData{
|
data: bReactorEventData{
|
||||||
peerId: src.ID(),
|
peerId: src.ID(),
|
||||||
@ -249,11 +249,11 @@ func (bcR *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte)
|
|||||||
length: len(msgBytes),
|
length: len(msgBytes),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
bcR.sendMessageToFSM(msgData)
|
bcR.messagesForFSMCh <- msgForFSM
|
||||||
|
|
||||||
case *bcStatusResponseMessage:
|
case *bcStatusResponseMessage:
|
||||||
// Got a peer status. Unverified.
|
// Got a peer status. Unverified.
|
||||||
msgData := bcReactorMessage{
|
msgForFSM := bcReactorMessage{
|
||||||
event: statusResponseEv,
|
event: statusResponseEv,
|
||||||
data: bReactorEventData{
|
data: bReactorEventData{
|
||||||
peerId: src.ID(),
|
peerId: src.ID(),
|
||||||
@ -261,18 +261,13 @@ func (bcR *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte)
|
|||||||
length: len(msgBytes),
|
length: len(msgBytes),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
bcR.sendMessageToFSM(msgData)
|
bcR.messagesForFSMCh <- msgForFSM
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bcR.Logger.Error(fmt.Sprintf("unknown message type %v", reflect.TypeOf(msg)))
|
bcR.Logger.Error(fmt.Sprintf("unknown message type %v", reflect.TypeOf(msg)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bcR *BlockchainReactor) sendMessageToFSM(msg bcReactorMessage) {
|
|
||||||
bcR.Logger.Debug("send message to FSM for processing", "msg", msg.String())
|
|
||||||
bcR.messagesForFSMCh <- msg
|
|
||||||
}
|
|
||||||
|
|
||||||
// poolRoutine receives and handles messages from the Receive() routine and from the FSM
|
// poolRoutine receives and handles messages from the Receive() routine and from the FSM
|
||||||
func (bcR *BlockchainReactor) poolRoutine() {
|
func (bcR *BlockchainReactor) poolRoutine() {
|
||||||
|
|
||||||
@ -280,14 +275,12 @@ func (bcR *BlockchainReactor) poolRoutine() {
|
|||||||
|
|
||||||
processReceivedBlockTicker := time.NewTicker(trySyncIntervalMS * time.Millisecond)
|
processReceivedBlockTicker := time.NewTicker(trySyncIntervalMS * time.Millisecond)
|
||||||
sendBlockRequestTicker := time.NewTicker(trySendIntervalMS * time.Millisecond)
|
sendBlockRequestTicker := time.NewTicker(trySendIntervalMS * time.Millisecond)
|
||||||
|
|
||||||
statusUpdateTicker := time.NewTicker(statusUpdateIntervalSeconds * time.Second)
|
statusUpdateTicker := time.NewTicker(statusUpdateIntervalSeconds * time.Second)
|
||||||
|
doProcessBlockCh := make(chan struct{}, 1)
|
||||||
|
|
||||||
lastHundred := time.Now()
|
lastHundred := time.Now()
|
||||||
lastRate := 0.0
|
lastRate := 0.0
|
||||||
|
|
||||||
doProcessBlockCh := make(chan struct{}, 1)
|
|
||||||
|
|
||||||
ForLoop:
|
ForLoop:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@ -341,18 +334,25 @@ ForLoop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
case msg := <-bcR.messagesForFSMCh:
|
case msg := <-bcR.messagesForFSMCh:
|
||||||
|
// Sent from the Receive() routine when status (statusResponseEv) and
|
||||||
|
// block (blockResponseEv) response events are received
|
||||||
_ = bcR.fsm.handle(&msg)
|
_ = bcR.fsm.handle(&msg)
|
||||||
|
|
||||||
case msg := <-bcR.errorsForFSMCh:
|
case msg := <-bcR.errorsForFSMCh:
|
||||||
|
// Sent from the switch.RemovePeer() routine (RemovePeerEv) and
|
||||||
|
// FSM state timer expiry routine (stateTimeoutEv).
|
||||||
_ = bcR.fsm.handle(&msg)
|
_ = bcR.fsm.handle(&msg)
|
||||||
|
|
||||||
case msg := <-bcR.eventsFromFSMCh:
|
case msg := <-bcR.eventsFromFSMCh:
|
||||||
switch msg.event {
|
switch msg.event {
|
||||||
case syncFinishedEv:
|
case syncFinishedEv:
|
||||||
|
// Sent from the FSM when it enters finished state.
|
||||||
break ForLoop
|
break ForLoop
|
||||||
case peerErrorEv:
|
case peerErrorEv:
|
||||||
|
// Sent from the FSM when it detects peer error
|
||||||
bcR.reportPeerErrorToSwitch(msg.data.err, msg.data.peerID)
|
bcR.reportPeerErrorToSwitch(msg.data.err, msg.data.peerID)
|
||||||
if msg.data.err == errNoPeerResponse {
|
if msg.data.err == errNoPeerResponse {
|
||||||
|
// Sent from the peer timeout handler routine
|
||||||
_ = bcR.fsm.handle(&bcReactorMessage{
|
_ = bcR.fsm.handle(&bcReactorMessage{
|
||||||
event: peerRemoveEv,
|
event: peerRemoveEv,
|
||||||
data: bReactorEventData{
|
data: bReactorEventData{
|
||||||
@ -360,6 +360,9 @@ ForLoop:
|
|||||||
err: msg.data.err,
|
err: msg.data.err,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
// For slow peers, or errors due to blocks received from wrong peer
|
||||||
|
// the FSM had already removed the peers
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
bcR.Logger.Error("Event from FSM not supported", "type", msg.event)
|
bcR.Logger.Error("Event from FSM not supported", "type", msg.event)
|
||||||
@ -480,7 +483,7 @@ func (bcR *BlockchainReactor) resetStateTimer(name string, timer **time.Timer, t
|
|||||||
stateName: name,
|
stateName: name,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
bcR.sendMessageToFSM(msg)
|
bcR.errorsForFSMCh <- msg
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
(*timer).Reset(timeout)
|
(*timer).Reset(timeout)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# ADR 041: Blockchain Reactor Design
|
# ADR 042: Blockchain Reactor Design
|
||||||
|
|
||||||
Author: @ancaz
|
Author: @ancaz
|
||||||
|
|
||||||
@ -187,19 +187,19 @@ H: The FSM times out in `waitForPeer` state, moves to `finished` state where it
|
|||||||
#### 2. Typical Fast Sync
|
#### 2. Typical Fast Sync
|
||||||
|
|
||||||
S: A node fast syncs blocks from honest peers and eventually downloads and executes the penultimate block.
|
S: A node fast syncs blocks from honest peers and eventually downloads and executes the penultimate block.
|
||||||
|
|
||||||
H: The FSM in `waitForBlock` state will receive the processedBlockEv from the reactor and detect that the termination height is achieved.
|
H: The FSM in `waitForBlock` state will receive the processedBlockEv from the reactor and detect that the termination height is achieved.
|
||||||
|
|
||||||
#### 3. Peer Fakes "Big" Height
|
#### 3. Peer Claims Big Height but no Blocks
|
||||||
|
|
||||||
S: In this scenario a faulty peer claims a big height (for which there are no blocks).
|
S: In this scenario a faulty peer claims a big height (for which there are no blocks).
|
||||||
H: The requests for the non-existing block will timeout, the peer removed and the pool's maxPeerHeight updated. FSM checks if the termination height is achieved when peers are removed.
|
|
||||||
|
|
||||||
S': A variation of this scenario is a faulty peer that claims a big height and after receiving the Block request for an non-existing block sends an unsolicited Status response with a lower height.
|
H: The requests for the non-existing block will timeout, the peer removed and the pool's maxPeerHeight updated. FSM checks if the termination height is achieved when peers are removed.
|
||||||
H': FSM updates the peer height and check if the termination height is achieved.
|
|
||||||
|
|
||||||
#### 4. Highest Peer Removed or Updated to Short
|
#### 4. Highest Peer Removed or Updated to Short
|
||||||
|
|
||||||
S: The fast sync node is caught up with all peers except one tall peer. The tall peer is removed or it sends Status response with low height.
|
S: The fast sync node is caught up with all peers except one tall peer. The tall peer is removed or it sends Status response with low height.
|
||||||
|
|
||||||
H: FSM checks termination condition on peer removal and updates.
|
H: FSM checks termination condition on peer removal and updates.
|
||||||
|
|
||||||
#### 5. Block At Current Height Delayed
|
#### 5. Block At Current Height Delayed
|
||||||
|
Loading…
x
Reference in New Issue
Block a user