network: use local timestamp to decide when to ping

We don't and we won't have synchronized clocks in the network so the only
timestamp that we can compare our local time with is the one made
ourselves. What this ping mechanism is used for is to recover from missing the
block broadcast, thus it's appropriate for it to trigger after X seconds of
the local time since the last block received.

Relates to #430.
This commit is contained in:
Roman Khimov 2020-01-20 17:39:59 +03:00
parent a8252ecc05
commit 62092c703d
2 changed files with 14 additions and 9 deletions

View file

@ -68,6 +68,8 @@ type (
quit chan struct{}
connected *atomic.Bool
// Time of the last block receival.
lastBlockTS *atomic.Int64
log *zap.Logger
}
@ -101,6 +103,7 @@ func NewServer(config ServerConfig, chain core.Blockchainer, log *zap.Logger) *S
unregister: make(chan peerDrop),
peers: make(map[Peer]bool),
connected: atomic.NewBool(false),
lastBlockTS: atomic.NewInt64(0),
log: log,
}
@ -359,6 +362,7 @@ func (s *Server) handleHeadersCmd(p Peer, headers *payload.Headers) {
// handleBlockCmd processes the received block received from its peer.
func (s *Server) handleBlockCmd(p Peer, block *block.Block) error {
s.lastBlockTS.Store(time.Now().UTC().Unix())
return s.bQueue.putBlock(block)
}
@ -658,6 +662,12 @@ func (s *Server) handleNewPayload(p *consensus.Payload) {
s.relayInventoryCmd(CMDInv, payload.ConsensusType, p.Hash())
}
// getLastBlockTime returns unix timestamp for the moment when the last block
// was received.
func (s *Server) getLastBlockTime() int64 {
return s.lastBlockTS.Load()
}
func (s *Server) requestTx(hashes ...util.Uint256) {
if len(hashes) == 0 {
return

View file

@ -208,15 +208,10 @@ func (p *TCPPeer) StartProtocol() {
if p.LastBlockIndex() > p.server.chain.BlockHeight() {
err = p.server.requestBlocks(p)
} else {
block, errGetBlock := p.server.chain.GetBlock(p.server.chain.CurrentBlockHash())
if errGetBlock != nil {
err = errGetBlock
} else {
diff := uint32(time.Now().UTC().Unix()) - block.Timestamp
if diff > uint32(p.server.PingInterval/time.Second) {
p.UpdatePingSent(p.GetPingSent() + 1)
err = p.EnqueueMessage(NewMessage(p.server.Net, CMDPing, payload.NewPing(p.server.id, p.server.chain.HeaderHeight())))
}
diff := time.Now().UTC().Unix() - p.server.getLastBlockTime()
if diff > int64(p.server.PingInterval/time.Second) {
p.UpdatePingSent(p.GetPingSent() + 1)
err = p.EnqueueMessage(NewMessage(p.server.Net, CMDPing, payload.NewPing(p.server.id, p.server.chain.HeaderHeight())))
}
}
if err == nil {