2015-03-22 19:00:08 -07:00
|
|
|
package blockchain
|
2015-03-22 03:30:22 -07:00
|
|
|
|
|
|
|
import (
|
2018-02-07 13:22:41 +04:00
|
|
|
"fmt"
|
2019-04-13 09:23:43 -04:00
|
|
|
"sort"
|
2015-03-22 03:30:22 -07:00
|
|
|
|
2018-07-01 22:36:49 -04:00
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
2018-01-03 11:29:19 +01:00
|
|
|
"github.com/tendermint/tendermint/p2p"
|
|
|
|
"github.com/tendermint/tendermint/types"
|
2015-03-22 03:30:22 -07:00
|
|
|
)
|
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
type blockPool struct {
|
|
|
|
logger log.Logger
|
2019-05-15 18:33:12 -04:00
|
|
|
// Set of peers that have sent status responses, with height bigger than pool.height
|
|
|
|
peers map[p2p.ID]*bpPeer
|
|
|
|
// Set of block heights and the corresponding peers from where a block response is expected or has been received.
|
2019-04-13 09:23:43 -04:00
|
|
|
blocks map[int64]p2p.ID
|
|
|
|
|
2019-05-15 23:33:19 -04:00
|
|
|
plannedRequests map[int64]struct{} // list of blocks to be assigned peers for blockRequest
|
|
|
|
nextRequestHeight int64 // next height to be added to plannedRequests
|
2019-04-13 09:23:43 -04:00
|
|
|
|
2019-05-15 18:33:12 -04:00
|
|
|
height int64 // height of next block to execute
|
2019-04-13 09:23:43 -04:00
|
|
|
maxPeerHeight int64 // maximum height of all peers
|
2019-06-02 19:03:51 +02:00
|
|
|
toBcR bcReactor
|
2019-04-13 09:23:43 -04:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
func NewBlockPool(height int64, toBcR bcReactor) *blockPool {
|
2019-04-13 09:23:43 -04:00
|
|
|
return &blockPool{
|
|
|
|
peers: make(map[p2p.ID]*bpPeer),
|
|
|
|
maxPeerHeight: 0,
|
|
|
|
blocks: make(map[int64]p2p.ID),
|
2019-05-15 23:33:19 -04:00
|
|
|
plannedRequests: make(map[int64]struct{}),
|
2019-04-13 09:23:43 -04:00
|
|
|
nextRequestHeight: height,
|
|
|
|
height: height,
|
|
|
|
toBcR: toBcR,
|
|
|
|
}
|
2015-03-22 03:30:22 -07:00
|
|
|
}
|
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
func (pool *blockPool) String() string {
|
|
|
|
peerStr := fmt.Sprintf("Pool Peers:")
|
|
|
|
for _, p := range pool.peers {
|
|
|
|
peerStr += fmt.Sprintf("%v,", p)
|
2015-03-22 03:30:22 -07:00
|
|
|
}
|
2019-04-13 09:23:43 -04:00
|
|
|
return peerStr
|
2015-03-22 03:30:22 -07:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) SetLogger(l log.Logger) {
|
2019-04-13 09:23:43 -04:00
|
|
|
pool.logger = l
|
2015-09-09 21:44:48 -07:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) ReachedMaxHeight() bool {
|
2019-05-15 18:33:12 -04:00
|
|
|
return pool.height >= pool.maxPeerHeight
|
2015-03-22 03:30:22 -07:00
|
|
|
}
|
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
func (pool *blockPool) rescheduleRequest(peerID p2p.ID, height int64) {
|
2019-05-15 09:08:02 -04:00
|
|
|
pool.logger.Info("reschedule requests made to peer for height ", "peerID", peerID, "height", height)
|
2019-05-15 23:33:19 -04:00
|
|
|
pool.plannedRequests[height] = struct{}{}
|
2019-04-13 09:23:43 -04:00
|
|
|
delete(pool.blocks, height)
|
2019-06-02 19:03:51 +02:00
|
|
|
pool.peers[peerID].RemoveBlockAtHeight(height)
|
2019-04-13 09:23:43 -04:00
|
|
|
}
|
2015-03-24 11:02:30 -07:00
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
// Updates the pool's max height. If no peers are left maxPeerHeight is set to 0.
|
|
|
|
func (pool *blockPool) updateMaxPeerHeight() {
|
2019-05-08 22:23:23 -04:00
|
|
|
var newMax int64
|
2019-04-13 09:23:43 -04:00
|
|
|
for _, peer := range pool.peers {
|
2019-06-02 19:03:51 +02:00
|
|
|
peerHeight := peer.GetHeight()
|
|
|
|
if peerHeight > newMax {
|
|
|
|
newMax = peerHeight
|
2015-10-12 16:49:46 -07:00
|
|
|
}
|
2015-03-22 03:30:22 -07:00
|
|
|
}
|
2019-05-08 22:23:23 -04:00
|
|
|
pool.maxPeerHeight = newMax
|
2015-03-22 12:46:53 -07:00
|
|
|
}
|
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
// Adds a new peer or updates an existing peer with a new height.
|
2019-05-15 10:04:29 -04:00
|
|
|
// If a new peer is too short it is not added.
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) UpdatePeer(peerID p2p.ID, height int64) error {
|
2019-04-13 09:23:43 -04:00
|
|
|
peer := pool.peers[peerID]
|
2019-05-15 09:08:02 -04:00
|
|
|
oldHeight := int64(0)
|
|
|
|
if peer != nil {
|
2019-06-02 19:03:51 +02:00
|
|
|
oldHeight = peer.GetHeight()
|
2019-05-15 09:08:02 -04:00
|
|
|
}
|
2019-05-15 23:33:19 -04:00
|
|
|
pool.logger.Info("updatePeer", "peerID", peerID, "height", height, "old_height", oldHeight)
|
2015-03-22 03:30:22 -07:00
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
if peer == nil {
|
2019-05-15 10:04:29 -04:00
|
|
|
if height < pool.height {
|
|
|
|
pool.logger.Info("Peer height too small", "peer", peerID, "height", height, "fsm_height", pool.height)
|
|
|
|
return errPeerTooShort
|
|
|
|
}
|
2019-04-13 09:23:43 -04:00
|
|
|
// Add new peer.
|
2019-06-02 19:03:51 +02:00
|
|
|
peer = NewBPPeer(peerID, height, pool.toBcR.sendPeerError, nil)
|
|
|
|
peer.SetLogger(pool.logger.With("peer", peerID))
|
2015-08-18 10:51:55 -07:00
|
|
|
pool.peers[peerID] = peer
|
2019-04-13 09:23:43 -04:00
|
|
|
} else {
|
2019-05-15 10:04:29 -04:00
|
|
|
// Check if peer is lowering its height. This is not allowed.
|
2019-06-02 19:03:51 +02:00
|
|
|
if height < peer.GetHeight() {
|
|
|
|
pool.RemovePeer(peerID, errPeerLowersItsHeight)
|
2019-05-15 10:04:29 -04:00
|
|
|
return errPeerLowersItsHeight
|
2019-04-13 09:23:43 -04:00
|
|
|
}
|
2019-05-15 10:04:29 -04:00
|
|
|
// Update existing peer.
|
2019-06-02 19:03:51 +02:00
|
|
|
peer.SetHeight(height)
|
2015-03-24 11:02:30 -07:00
|
|
|
}
|
2017-10-26 18:29:23 -04:00
|
|
|
|
2019-05-15 18:33:12 -04:00
|
|
|
// Update the pool's maxPeerHeight if needed. Note that for updates it can only increase or left unchanged.
|
2019-04-13 09:23:43 -04:00
|
|
|
pool.updateMaxPeerHeight()
|
2015-03-24 11:02:30 -07:00
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
return nil
|
2015-03-22 12:46:53 -07:00
|
|
|
}
|
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
// Stops the peer timer and deletes the peer. Recomputes the max peer height.
|
2019-05-15 18:33:12 -04:00
|
|
|
func (pool *blockPool) deletePeer(peer *bpPeer) {
|
|
|
|
if peer == nil {
|
|
|
|
return
|
|
|
|
}
|
2019-06-02 19:03:51 +02:00
|
|
|
peer.StopBlockResponseTimer()
|
|
|
|
delete(pool.peers, peer.ID())
|
2019-03-20 03:59:33 +03:00
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
if peer.GetHeight() == pool.maxPeerHeight {
|
2019-05-15 18:33:12 -04:00
|
|
|
pool.updateMaxPeerHeight()
|
2019-03-20 03:59:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
// Removes any blocks and requests associated with the peer and deletes the peer.
|
|
|
|
// Also triggers new requests if blocks have been removed.
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) RemovePeer(peerID p2p.ID, err error) {
|
2019-04-13 09:23:43 -04:00
|
|
|
peer := pool.peers[peerID]
|
|
|
|
if peer == nil {
|
|
|
|
return
|
|
|
|
}
|
2019-05-15 23:33:19 -04:00
|
|
|
pool.logger.Info("removing peer", "peerID", peerID, "error", err)
|
|
|
|
|
2019-05-15 18:33:12 -04:00
|
|
|
// Reschedule the block requests made to the peer, or received and not processed yet.
|
|
|
|
// Note that some of the requests may be removed further down.
|
2019-05-20 23:32:59 -04:00
|
|
|
for h := range pool.peers[peerID].blocks {
|
2019-04-13 09:23:43 -04:00
|
|
|
pool.rescheduleRequest(peerID, h)
|
2019-03-03 04:21:21 +08:00
|
|
|
}
|
2015-03-22 12:46:53 -07:00
|
|
|
|
2019-05-15 18:33:12 -04:00
|
|
|
oldMaxPeerHeight := pool.maxPeerHeight
|
|
|
|
// Delete the peer. This operation may result in the pool's maxPeerHeight being lowered.
|
|
|
|
pool.deletePeer(peer)
|
|
|
|
|
|
|
|
// Check if the pool's maxPeerHeight has been lowered.
|
|
|
|
// This may happen if the tallest peer has been removed.
|
|
|
|
if oldMaxPeerHeight > pool.maxPeerHeight {
|
|
|
|
// Remove any planned requests for heights over the new maxPeerHeight.
|
2019-05-15 23:33:19 -04:00
|
|
|
for h := range pool.plannedRequests {
|
2019-05-15 18:33:12 -04:00
|
|
|
if h > pool.maxPeerHeight {
|
2019-05-15 23:33:19 -04:00
|
|
|
delete(pool.plannedRequests, h)
|
2019-05-15 18:33:12 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Adjust the nextRequestHeight to the new max plus one.
|
|
|
|
if pool.nextRequestHeight > pool.maxPeerHeight {
|
|
|
|
pool.nextRequestHeight = pool.maxPeerHeight + 1
|
|
|
|
}
|
|
|
|
}
|
2019-04-13 09:23:43 -04:00
|
|
|
}
|
2015-03-24 11:02:30 -07:00
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
// Called every time FSM advances its height.
|
|
|
|
func (pool *blockPool) removeShortPeers() {
|
2015-03-25 11:33:39 -07:00
|
|
|
for _, peer := range pool.peers {
|
2019-06-02 19:03:51 +02:00
|
|
|
if peer.GetHeight() < pool.height {
|
|
|
|
pool.RemovePeer(peer.ID(), nil)
|
2015-08-18 10:51:55 -07:00
|
|
|
}
|
2015-03-22 03:30:22 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-15 23:26:07 -04:00
|
|
|
func (pool *blockPool) removeBadPeers() {
|
|
|
|
pool.removeShortPeers()
|
|
|
|
for _, peer := range pool.peers {
|
2019-06-02 19:03:51 +02:00
|
|
|
if err := peer.IsGood(); err != nil {
|
|
|
|
pool.RemovePeer(peer.ID(), err)
|
|
|
|
pool.toBcR.sendPeerError(err, peer.ID())
|
2019-04-15 23:26:07 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-15 23:33:19 -04:00
|
|
|
// Make a batch of requests sorted by height. The parameter 'maxNumRequests' includes the number of block requests
|
|
|
|
// already made.
|
2019-05-15 09:08:02 -04:00
|
|
|
func (pool *blockPool) makeRequestBatch(maxNumRequests int32) []int {
|
2019-04-15 23:26:07 -04:00
|
|
|
pool.removeBadPeers()
|
2019-05-15 23:33:19 -04:00
|
|
|
// At this point pool.requests may include heights for requests to be redone due to removal of peers:
|
|
|
|
// - peers timed out or were removed by switch
|
|
|
|
// - FSM timed out on waiting to advance the block execution due to missing blocks at h or h+1
|
|
|
|
// Check if more requests should be tried by subtracting the number of requests already made from the maximum allowed
|
|
|
|
numNeeded := int(maxNumRequests) - len(pool.blocks)
|
|
|
|
for len(pool.plannedRequests) < numNeeded {
|
2019-04-15 23:26:07 -04:00
|
|
|
if pool.nextRequestHeight > pool.maxPeerHeight {
|
|
|
|
break
|
|
|
|
}
|
2019-05-15 23:33:19 -04:00
|
|
|
pool.plannedRequests[pool.nextRequestHeight] = struct{}{}
|
2019-04-15 23:26:07 -04:00
|
|
|
pool.nextRequestHeight++
|
|
|
|
}
|
|
|
|
|
2019-05-15 23:33:19 -04:00
|
|
|
heights := make([]int, 0, len(pool.plannedRequests))
|
|
|
|
for k := range pool.plannedRequests {
|
2019-04-15 23:26:07 -04:00
|
|
|
heights = append(heights, int(k))
|
|
|
|
}
|
|
|
|
sort.Ints(heights)
|
|
|
|
return heights
|
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) MakeNextRequests(maxNumRequests int32) {
|
2019-05-15 09:08:02 -04:00
|
|
|
heights := pool.makeRequestBatch(maxNumRequests)
|
|
|
|
pool.logger.Info("makeNextRequests will make following requests", "number", len(heights), "heights", heights)
|
2019-04-15 23:26:07 -04:00
|
|
|
|
|
|
|
for _, height := range heights {
|
|
|
|
h := int64(height)
|
2019-04-28 22:03:26 -04:00
|
|
|
if !pool.sendRequest(h) {
|
2019-05-15 23:33:19 -04:00
|
|
|
// If a good peer was not found for sending the request at height h then return,
|
|
|
|
// as it shouldn't be possible to find a peer for h+1.
|
2019-04-15 23:26:07 -04:00
|
|
|
return
|
|
|
|
}
|
2019-05-15 23:33:19 -04:00
|
|
|
delete(pool.plannedRequests, h)
|
2019-04-15 23:26:07 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-28 22:03:26 -04:00
|
|
|
func (pool *blockPool) sendRequest(height int64) bool {
|
2019-04-15 23:26:07 -04:00
|
|
|
for _, peer := range pool.peers {
|
2019-06-02 19:03:51 +02:00
|
|
|
if peer.GetNumPendingBlockRequests() >= int32(maxRequestsPerPeer) {
|
2019-04-15 23:26:07 -04:00
|
|
|
continue
|
|
|
|
}
|
2019-06-02 19:03:51 +02:00
|
|
|
if peer.GetHeight() < height {
|
2019-04-15 23:26:07 -04:00
|
|
|
continue
|
|
|
|
}
|
2019-05-07 21:06:43 -04:00
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
err := pool.toBcR.sendBlockRequest(peer.ID(), height)
|
2019-05-15 23:33:19 -04:00
|
|
|
if err == errNilPeerForBlockRequest {
|
2019-05-15 09:08:02 -04:00
|
|
|
// Switch does not have this peer, remove it and continue to look for another peer.
|
2019-06-02 19:03:51 +02:00
|
|
|
pool.logger.Error("switch does not have peer..removing peer selected for height", "peer", peer.ID(), "height", height)
|
|
|
|
pool.RemovePeer(peer.ID(), err)
|
2019-05-15 09:08:02 -04:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2019-05-15 23:33:19 -04:00
|
|
|
if err == errSendQueueFull {
|
2019-06-02 19:03:51 +02:00
|
|
|
pool.logger.Error("peer queue is full", "peer", peer.ID(), "height", height)
|
2019-05-15 23:33:19 -04:00
|
|
|
continue
|
2019-04-15 23:26:07 -04:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
pool.logger.Info("assigned request to peer", "peer", peer.ID(), "height", height)
|
2019-05-15 23:33:19 -04:00
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
pool.blocks[height] = peer.ID()
|
|
|
|
peer.SetBlockAtHeight(height, nil)
|
|
|
|
peer.IncrPending()
|
2019-04-15 23:26:07 -04:00
|
|
|
|
2019-04-28 22:03:26 -04:00
|
|
|
return true
|
2019-04-15 23:26:07 -04:00
|
|
|
}
|
|
|
|
pool.logger.Error("could not find peer to send request for block at height", "height", height)
|
2019-04-28 22:03:26 -04:00
|
|
|
return false
|
2019-04-15 23:26:07 -04:00
|
|
|
}
|
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
// Validates that the block comes from the peer it was expected from and stores it in the 'blocks' map.
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) AddBlock(peerID p2p.ID, block *types.Block, blockSize int) error {
|
2019-05-15 18:33:12 -04:00
|
|
|
peer, ok := pool.peers[peerID]
|
|
|
|
if !ok {
|
2019-05-15 23:33:19 -04:00
|
|
|
pool.logger.Error("peer does not exist in the pool", "peer", peerID, "block_received", block.Height)
|
2019-04-13 09:23:43 -04:00
|
|
|
return errBadDataFromPeer
|
2018-11-26 15:31:11 -05:00
|
|
|
}
|
2019-06-02 19:03:51 +02:00
|
|
|
b, err := pool.peers[peerID].GetBlockAtHeight(block.Height)
|
|
|
|
if err == errMissingRequest {
|
2019-04-13 09:23:43 -04:00
|
|
|
pool.logger.Error("peer sent us a block we didn't expect", "peer", peerID, "blockHeight", block.Height)
|
|
|
|
if expPeerID, pok := pool.blocks[block.Height]; pok {
|
|
|
|
pool.logger.Error("expected this block from peer", "peer", expPeerID)
|
|
|
|
}
|
|
|
|
return errBadDataFromPeer
|
2017-09-06 13:11:47 -04:00
|
|
|
}
|
2019-04-13 09:23:43 -04:00
|
|
|
if b != nil {
|
|
|
|
pool.logger.Error("already have a block for height", "height", block.Height)
|
|
|
|
return errBadDataFromPeer
|
2015-03-22 03:30:22 -07:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
peer.SetBlockAtHeight(block.Height, block)
|
|
|
|
peer.DecrPending(blockSize)
|
2019-05-15 23:33:19 -04:00
|
|
|
pool.logger.Info("added new block", "height", block.Height, "from_peer", peerID,
|
2019-06-02 19:03:51 +02:00
|
|
|
"total_pool_blocks", len(pool.blocks), "peer_numPendingBlockRequests", peer.GetNumPendingBlockRequests())
|
2019-04-13 09:23:43 -04:00
|
|
|
return nil
|
2015-03-24 11:02:30 -07:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
type blockData struct {
|
|
|
|
block *types.Block
|
|
|
|
peer *bpPeer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pool *blockPool) GetBlockAndPeerAtHeight(height int64) (bData *blockData, err error) {
|
2019-04-13 09:23:43 -04:00
|
|
|
peerID := pool.blocks[height]
|
|
|
|
peer := pool.peers[peerID]
|
|
|
|
if peer == nil {
|
2019-06-02 19:03:51 +02:00
|
|
|
return nil, errMissingBlock
|
2019-02-06 18:20:10 +04:00
|
|
|
}
|
2015-03-22 03:30:22 -07:00
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
block, err := peer.GetBlockAtHeight(height)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2019-04-13 09:23:43 -04:00
|
|
|
}
|
2016-06-28 18:02:27 -07:00
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
return &blockData{peer: peer, block: block}, nil
|
2017-05-02 11:53:32 +04:00
|
|
|
|
2015-03-22 03:30:22 -07:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) GetNextTwoBlocks() (first, second *blockData, err error) {
|
|
|
|
first, err = pool.GetBlockAndPeerAtHeight(pool.height)
|
|
|
|
second, err2 := pool.GetBlockAndPeerAtHeight(pool.height + 1)
|
2019-04-13 09:23:43 -04:00
|
|
|
if err == nil {
|
|
|
|
err = err2
|
2015-08-18 10:51:55 -07:00
|
|
|
}
|
2019-04-13 09:23:43 -04:00
|
|
|
return
|
2017-05-02 11:53:32 +04:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
// Remove the peers that sent us the first two blocks, blocks are removed by RemovePeer().
|
|
|
|
func (pool *blockPool) InvalidateFirstTwoBlocks(err error) {
|
|
|
|
first, err1 := pool.GetBlockAndPeerAtHeight(pool.height)
|
|
|
|
second, err2 := pool.GetBlockAndPeerAtHeight(pool.height + 1)
|
2015-08-18 10:51:55 -07:00
|
|
|
|
2019-04-13 09:23:43 -04:00
|
|
|
if err1 == nil {
|
2019-06-02 19:03:51 +02:00
|
|
|
pool.RemovePeer(first.peer.ID(), err)
|
2015-08-18 10:51:55 -07:00
|
|
|
}
|
2019-04-13 09:23:43 -04:00
|
|
|
if err2 == nil {
|
2019-06-02 19:03:51 +02:00
|
|
|
pool.RemovePeer(second.peer.ID(), err)
|
2015-08-18 10:51:55 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) ProcessedCurrentHeightBlock() {
|
2019-04-13 09:23:43 -04:00
|
|
|
peerID, peerOk := pool.blocks[pool.height]
|
|
|
|
if peerOk {
|
2019-06-02 19:03:51 +02:00
|
|
|
pool.peers[peerID].RemoveBlockAtHeight(pool.height)
|
2015-08-18 10:51:55 -07:00
|
|
|
}
|
2019-04-13 09:23:43 -04:00
|
|
|
delete(pool.blocks, pool.height)
|
|
|
|
pool.logger.Debug("processed and removed block at height", "height", pool.height)
|
|
|
|
pool.height++
|
|
|
|
pool.removeShortPeers()
|
2015-08-18 10:51:55 -07:00
|
|
|
}
|
|
|
|
|
2019-05-08 18:28:18 -04:00
|
|
|
// This function is called when the FSM is not able to make progress for a certain amount of time.
|
|
|
|
// This happens if the block at either pool.height or pool.height+1 has not been delivered during this time.
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) RemovePeerAtCurrentHeights(err error) {
|
2019-05-07 21:06:43 -04:00
|
|
|
peerID := pool.blocks[pool.height]
|
2019-05-08 18:28:18 -04:00
|
|
|
peer, ok := pool.peers[peerID]
|
2019-06-02 19:03:51 +02:00
|
|
|
if ok {
|
|
|
|
if _, err := peer.GetBlockAtHeight(pool.height); err != nil {
|
|
|
|
pool.logger.Info("removing peer that hasn't sent block at pool.height",
|
|
|
|
"peer", peerID, "height", pool.height)
|
|
|
|
pool.RemovePeer(peerID, err)
|
|
|
|
return
|
|
|
|
}
|
2019-04-28 22:03:26 -04:00
|
|
|
}
|
2019-05-08 18:28:18 -04:00
|
|
|
peerID = pool.blocks[pool.height+1]
|
|
|
|
peer, ok = pool.peers[peerID]
|
2019-06-02 19:03:51 +02:00
|
|
|
if ok {
|
|
|
|
if _, err := peer.GetBlockAtHeight(pool.height + 1); err != nil {
|
|
|
|
pool.logger.Info("removing peer that hasn't sent block at pool.height+1",
|
|
|
|
"peer", peerID, "height", pool.height+1)
|
|
|
|
pool.RemovePeer(peerID, err)
|
|
|
|
return
|
|
|
|
}
|
2019-05-08 18:28:18 -04:00
|
|
|
}
|
2019-05-15 09:08:02 -04:00
|
|
|
pool.logger.Info("no peers assigned to blocks at current height or blocks already delivered",
|
|
|
|
"height", pool.height)
|
2019-04-28 22:03:26 -04:00
|
|
|
}
|
|
|
|
|
2019-06-02 19:03:51 +02:00
|
|
|
func (pool *blockPool) Cleanup() {
|
2019-04-13 09:23:43 -04:00
|
|
|
for _, peer := range pool.peers {
|
2019-06-02 19:03:51 +02:00
|
|
|
peer.Cleanup()
|
2015-08-18 10:51:55 -07:00
|
|
|
}
|
|
|
|
}
|