network: request blocks when there is a ping with bigger than ours height

Turns out, C# node no longer broadcasts an Inv when it's creating a block,
instead it sends a ping and if we're not paying attention to the height
specified there we're technically missing a new block. Of course we'll get it
later after ping timer expiration and regular ping/pong sequence, but that's
delaying it for no good reason.
This commit is contained in:
Roman Khimov 2020-08-14 16:22:15 +03:00
parent 92f37a5d36
commit c8cc91eeee
4 changed files with 26 additions and 0 deletions

View file

@ -286,6 +286,11 @@ func (p *localPeer) SendPing(m *Message) error {
_ = p.EnqueueMessage(m)
return nil
}
func (p *localPeer) HandlePing(ping *payload.Ping) error {
p.lastBlockIndex = ping.LastBlockIndex
return nil
}
func (p *localPeer) HandlePong(pong *payload.Ping) error {
p.lastBlockIndex = pong.LastBlockIndex
p.pingSent--

View file

@ -67,6 +67,9 @@ type Peer interface {
HandleVersion(*payload.Version) error
HandleVersionAck() error
// HandlePing checks ping contents against Peer's state and updates it.
HandlePing(ping *payload.Ping) error
// HandlePong checks pong contents against Peer's state and updates it.
HandlePong(pong *payload.Ping) error
}

View file

@ -453,6 +453,16 @@ func (s *Server) handleBlockCmd(p Peer, block *block.Block) error {
// handlePing processes ping request.
func (s *Server) handlePing(p Peer, ping *payload.Ping) error {
err := p.HandlePing(ping)
if err != nil {
return err
}
if s.chain.BlockHeight() < ping.LastBlockIndex {
err = s.requestBlocks(p)
if err != nil {
return err
}
}
return p.EnqueueP2PMessage(NewMessage(CMDPong, payload.NewPing(s.chain.BlockHeight(), s.id)))
}

View file

@ -431,6 +431,14 @@ func (p *TCPPeer) SendPing(msg *Message) error {
return p.EnqueueMessage(msg)
}
// HandlePing handles a ping message received from the peer.
func (p *TCPPeer) HandlePing(ping *payload.Ping) error {
p.lock.Lock()
defer p.lock.Unlock()
p.lastBlockIndex = ping.LastBlockIndex
return nil
}
// HandlePong handles a pong message received from the peer and does appropriate
// accounting of outstanding pings and timeouts.
func (p *TCPPeer) HandlePong(pong *payload.Ping) error {