github.com/aaa256/atlantis@v0.0.0-20210707112435-42ee889287a2/swarm/pss/ping.go (about) 1 // Copyright 2018 The go-athereum Authors 2 // This file is part of the go-athereum library. 3 // 4 // The go-athereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-athereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-athereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // +build !nopssprotocol,!nopssping 18 19 package pss 20 21 import ( 22 "errors" 23 "time" 24 25 "github.com/athereum/go-athereum/p2p" 26 "github.com/athereum/go-athereum/p2p/protocols" 27 "github.com/athereum/go-athereum/swarm/log" 28 ) 29 30 // Generic ping protocol implementation for 31 // pss devp2p protocol emulation 32 type PingMsg struct { 33 Created time.Time 34 Pong bool // set if message is pong reply 35 } 36 37 type Ping struct { 38 Pong bool // toggle pong reply upon ping receive 39 OutC chan bool // trigger ping 40 InC chan bool // optional, report back to calling code 41 } 42 43 func (p *Ping) pingHandler(msg interface{}) error { 44 var pingmsg *PingMsg 45 var ok bool 46 if pingmsg, ok = msg.(*PingMsg); !ok { 47 return errors.New("invalid msg") 48 } 49 log.Debug("ping handler", "msg", pingmsg, "outc", p.OutC) 50 if p.InC != nil { 51 p.InC <- pingmsg.Pong 52 } 53 if p.Pong && !pingmsg.Pong { 54 p.OutC <- true 55 } 56 return nil 57 } 58 59 var PingProtocol = &protocols.Spec{ 60 Name: "psstest", 61 Version: 1, 62 MaxMsgSize: 1024, 63 Messages: []interface{}{ 64 PingMsg{}, 65 }, 66 } 67 68 var PingTopic = ProtocolTopic(PingProtocol) 69 70 func NewPingProtocol(ping *Ping) *p2p.Protocol { 71 return &p2p.Protocol{ 72 Name: PingProtocol.Name, 73 Version: PingProtocol.Version, 74 Length: uint64(PingProtocol.MaxMsgSize), 75 Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { 76 quitC := make(chan struct{}) 77 pp := protocols.NewPeer(p, rw, PingProtocol) 78 log.Trace("running pss vprotocol", "peer", p, "outc", ping.OutC) 79 go func() { 80 for { 81 select { 82 case ispong := <-ping.OutC: 83 pp.Send(&PingMsg{ 84 Created: time.Now(), 85 Pong: ispong, 86 }) 87 case <-quitC: 88 } 89 } 90 }() 91 err := pp.Run(ping.pingHandler) 92 quitC <- struct{}{} 93 return err 94 }, 95 } 96 }