| 285 | } |
| 286 | |
| 287 | func (pm *ProtocolManager) handlePeer(p *p2p.Peer, rw p2p.MsgReadWriter, version uint) error { |
| 288 | var ( |
| 289 | dporEngine = pm.engine.(*dpor.Dpor) |
| 290 | isMiner = dporEngine.IsDefaultProposer(dporEngine.Coinbase()) || dporEngine.IsCurrentOrFutureProposer(dporEngine.Coinbase()) |
| 291 | workAsValidator = dporEngine.IsValidator() |
| 292 | dporMode = dporEngine.Mode() |
| 293 | dporProtocol = dporEngine.Protocol() |
| 294 | isMinerOrValidator = isMiner || workAsValidator |
| 295 | handleTxs = !workAsValidator |
| 296 | handleDporMsgs = workAsValidator && dporMode == dpor.NormalMode |
| 297 | ) |
| 298 | |
| 299 | if dporMode == dpor.NormalMode && isMinerOrValidator { |
| 300 | for !dporProtocol.Available() { |
| 301 | log.Debug("dpor protocol is not available now, sleeping 5 seconds.") |
| 302 | time.Sleep(5 * time.Second) |
| 303 | } |
| 304 | log.Debug("now dpor protocol is available") |
| 305 | } |
| 306 | |
| 307 | // wrap up the peer |
| 308 | peer := pm.newPeer(int(version), p, rw) |
| 309 | |
| 310 | // either we quit or we wait on accepting a new peer by syncer |
| 311 | select { |
| 312 | case pm.newPeerCh <- peer: |
| 313 | pm.wg.Add(1) |
| 314 | defer pm.wg.Done() |
| 315 | |
| 316 | log.Debug("received a new peer", "id", p.ID().String(), "remote addr", p.RemoteAddr().String(), "local addr", p.LocalAddr().String(), "is default validator", backend.IsDefaultValidator(p.ID().String(), configs.GetDefaultValidators())) |
| 317 | |
| 318 | // add peer to manager.peers, this is for basic msg syncing |
| 319 | remoteIsMiner, err := pm.addPeer(peer, isMinerOrValidator) |
| 320 | if err != nil { |
| 321 | log.Debug("fail to add peer to cpc protocol manager's peer set", "peer.RemoteAddr", peer.RemoteAddr().String(), "local addr", peer.LocalAddr().String(), "peer.id", peer.IDString(), "err", err) |
| 322 | return err |
| 323 | } |
| 324 | |
| 325 | // defer to remove the peer |
| 326 | defer pm.removePeer(peer.id) |
| 327 | |
| 328 | log.Debug("is validator and remote is miner", "is validator", dporEngine.IsValidator(), "remote miner", remoteIsMiner, "id", p.ID().String(), "remote addr", p.RemoteAddr().String(), "local addr", p.LocalAddr().String()) |
| 329 | |
| 330 | // validator do not connect to civilian to avoid deny of service attack |
| 331 | if dporEngine.IsValidator() && !remoteIsMiner { |
| 332 | log.Warn("I am a validator, but the remote peer is neither a proposer, nor a validator, disconnecting", "peer.RemoteAddr", peer.RemoteAddr().String(), "peer.LocalAddr", peer.LocalAddr().String(), "peer.id", peer.IDString(), "err", err) |
| 333 | return nil |
| 334 | } |
| 335 | |
| 336 | log.Debug("done of handshake with peer", "id", p.ID().String(), "remote addr", p.RemoteAddr().String(), "local addr", p.LocalAddr().String()) |
| 337 | |
| 338 | // add peer to dpor.handler.dialer.peers, this is for proposers/validators communication |
| 339 | id, added := common.Address{}.Hex(), false |
| 340 | if dporMode == dpor.NormalMode && isMinerOrValidator && remoteIsMiner { |
| 341 | switch id, _, _, err = dporProtocol.AddPeer(int(version), peer.Peer, peer.rw); err { |
| 342 | case nil: |
| 343 | added = true |
| 344 | log.Debug("done of dpor subprotocol handshake with peer", "id", p.ID().String(), "remote addr", p.RemoteAddr().String(), "coinbase", id, "local addr", p.LocalAddr().String()) |