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  }