[NOD-1005] Use sm.isSynced to check whether should request blocks from invs (#721)

* [NOD-1005] Moved isSyncedForMining to netsync manager, and renamed to isSynced + removed isCurrent

* [NOD-1005] Use sm.isSynced to check whether should request blocks from invs

* [NOD-1005] Use private version of isSynced to avoid infinite loop

* [NOD-1005] Fix a few typos
This commit is contained in:
Svarog 2020-05-18 10:42:58 +03:00 committed by GitHub
parent 28681affda
commit eb8b841850
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 37 deletions

View File

@ -103,10 +103,10 @@ type processBlockMsg struct {
reply chan processBlockResponse
}
// isCurrentMsg is a message type to be sent across the message channel for
// isSyncedMsg is a message type to be sent across the message channel for
// requesting whether or not the sync manager believes it is synced with the
// currently connected peers.
type isCurrentMsg struct {
type isSyncedMsg struct {
reply chan bool
}
@ -839,7 +839,7 @@ func (sm *SyncManager) sendInvsFromRequestQueue(peer *peerpkg.Peer, state *peerS
if err != nil {
return err
}
if sm.current() {
if sm.syncPeer == nil || sm.isSynced() {
err := sm.addInvsToGetDataMessageFromQueue(gdmsg, state, wire.InvTypeBlock, wire.MaxInvPerGetDataMsg)
if err != nil {
return err
@ -968,8 +968,8 @@ out:
err: err,
}
case isCurrentMsg:
msg.reply <- sm.current()
case isSyncedMsg:
msg.reply <- sm.isSynced()
case pauseMsg:
// Wait until the sender unpauses the manager.
@ -1151,14 +1151,32 @@ func (sm *SyncManager) ProcessBlock(block *util.Block, flags blockdag.BehaviorFl
return response.isOrphan, response.err
}
// IsCurrent returns whether or not the sync manager believes it is synced with
// IsSynced returns whether or not the sync manager believes it is synced with
// the connected peers.
func (sm *SyncManager) IsCurrent() bool {
func (sm *SyncManager) IsSynced() bool {
reply := make(chan bool)
sm.msgChan <- isCurrentMsg{reply: reply}
sm.msgChan <- isSyncedMsg{reply: reply}
return <-reply
}
// isSynced checks if the node is synced enough based upon its worldview.
// This is used to determine if the node can support mining and requesting newly-mined blocks.
// To do that, first it checks if the selected tip timestamp is not older than maxTipAge. If that's the case, it means
// the node is synced since blocks' timestamps are not allowed to deviate too much into the future.
// If that's not the case it checks the rate it added new blocks to the DAG recently. If it's faster than
// blockRate * maxSyncRateDeviation it means the node is not synced, since when the node is synced it shouldn't add
// blocks to the DAG faster than the block rate.
func (sm *SyncManager) isSynced() bool {
const maxTipAge = 5 * time.Minute
isCloseToCurrentTime := sm.dag.Now().Sub(sm.dag.SelectedTipHeader().Timestamp) <= maxTipAge
if isCloseToCurrentTime {
return true
}
const maxSyncRateDeviation = 1.05
return sm.dag.IsSyncRateBelowThreshold(maxSyncRateDeviation)
}
// Pause pauses the sync manager until the returned channel is closed.
//
// Note that while paused, all peer and block processing is halted. The

View File

@ -4,6 +4,12 @@ import (
"bytes"
"encoding/hex"
"fmt"
"math/rand"
"strconv"
"strings"
"sync"
"time"
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/config"
"github.com/kaspanet/kaspad/mining"
@ -14,11 +20,6 @@ import (
"github.com/kaspanet/kaspad/util/random"
"github.com/kaspanet/kaspad/wire"
"github.com/pkg/errors"
"math/rand"
"strconv"
"strings"
"sync"
"time"
)
const (
@ -119,24 +120,6 @@ func handleGetBlockTemplate(s *Server, cmd interface{}, closeChan <-chan struct{
}
}
// isSyncedForMining checks if the node is synced enough for mining blocks
// on top of its world view.
// To do that, first it checks if the selected tip timestamp is not older than maxTipAge. If that's the case, it means
// the node is synced since blocks' timestamps are not allowed to deviate too much into the future.
// If that's not the case it checks the rate it added new blocks to the DAG recently. If it's faster than
// blockRate * maxSyncRateDeviation it means the node is not synced, since when the node is synced it shouldn't add
// blocks to the DAG faster than the block rate.
func isSyncedForMining(s *Server) bool {
const maxTipAge = 5 * time.Minute
isCloseToCurrentTime := s.cfg.DAG.Now().Sub(s.cfg.DAG.SelectedTipHeader().Timestamp) <= maxTipAge
if isCloseToCurrentTime {
return true
}
const maxSyncRateDeviation = 1.05
return s.cfg.DAG.IsSyncRateBelowThreshold(maxSyncRateDeviation)
}
// handleGetBlockTemplateRequest is a helper for handleGetBlockTemplate which
// deals with generating and returning block templates to the caller. It
// handles both long poll requests as specified by BIP 0022 as well as regular
@ -652,7 +635,7 @@ func (state *gbtWorkState) updateBlockTemplate(s *Server, useCoinbaseValue bool)
// This is not a straight-up error because the choice of whether
// to mine or not is the responsibility of the miner rather
// than the node's.
isSynced := isSyncedForMining(s)
isSynced := s.cfg.SyncMgr.IsSynced()
// Update work state to ensure another block template isn't
// generated until needed.

View File

@ -234,13 +234,13 @@ type rpcSyncMgr struct {
// Ensure rpcSyncMgr implements the rpcserverSyncManager interface.
var _ rpcserverSyncManager = (*rpcSyncMgr)(nil)
// IsCurrent returns whether or not the sync manager believes the DAG is
// IsSynced returns whether or not the sync manager believes the DAG is
// current as compared to the rest of the network.
//
// This function is safe for concurrent access and is part of the
// rpcserverSyncManager interface implementation.
func (b *rpcSyncMgr) IsCurrent() bool {
return b.syncMgr.IsCurrent()
func (b *rpcSyncMgr) IsSynced() bool {
return b.syncMgr.IsSynced()
}
// SubmitBlock submits the provided block to the network after processing it

View File

@ -723,9 +723,9 @@ type rpcserverConnManager interface {
// The interface contract requires that all of these methods are safe for
// concurrent access.
type rpcserverSyncManager interface {
// IsCurrent returns whether or not the sync manager believes the DAG
// IsSynced returns whether or not the sync manager believes the DAG
// is current as compared to the rest of the network.
IsCurrent() bool
IsSynced() bool
// SubmitBlock submits the provided block to the network after
// processing it locally.