github.com/julesgoullee/go-ethereum@v1.9.7/p2p/simulations/events.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package simulations
    18  
    19  import (
    20  	"fmt"
    21  	"time"
    22  )
    23  
    24  // EventType is the type of event emitted by a simulation network
    25  type EventType string
    26  
    27  const (
    28  	// EventTypeNode is the type of event emitted when a node is either
    29  	// created, started or stopped
    30  	EventTypeNode EventType = "node"
    31  
    32  	// EventTypeConn is the type of event emitted when a connection is
    33  	// is either established or dropped between two nodes
    34  	EventTypeConn EventType = "conn"
    35  
    36  	// EventTypeMsg is the type of event emitted when a p2p message it
    37  	// sent between two nodes
    38  	EventTypeMsg EventType = "msg"
    39  )
    40  
    41  // Event is an event emitted by a simulation network
    42  type Event struct {
    43  	// Type is the type of the event
    44  	Type EventType `json:"type"`
    45  
    46  	// Time is the time the event happened
    47  	Time time.Time `json:"time"`
    48  
    49  	// Control indicates whether the event is the result of a controlled
    50  	// action in the network
    51  	Control bool `json:"control"`
    52  
    53  	// Node is set if the type is EventTypeNode
    54  	Node *Node `json:"node,omitempty"`
    55  
    56  	// Conn is set if the type is EventTypeConn
    57  	Conn *Conn `json:"conn,omitempty"`
    58  
    59  	// Msg is set if the type is EventTypeMsg
    60  	Msg *Msg `json:"msg,omitempty"`
    61  
    62  	//Optionally provide data (currently for simulation frontends only)
    63  	Data interface{} `json:"data"`
    64  }
    65  
    66  // NewEvent creates a new event for the given object which should be either a
    67  // Node, Conn or Msg.
    68  //
    69  // The object is copied so that the event represents the state of the object
    70  // when NewEvent is called.
    71  func NewEvent(v interface{}) *Event {
    72  	event := &Event{Time: time.Now()}
    73  	switch v := v.(type) {
    74  	case *Node:
    75  		event.Type = EventTypeNode
    76  		node := *v
    77  		event.Node = &node
    78  	case *Conn:
    79  		event.Type = EventTypeConn
    80  		conn := *v
    81  		event.Conn = &conn
    82  	case *Msg:
    83  		event.Type = EventTypeMsg
    84  		msg := *v
    85  		event.Msg = &msg
    86  	default:
    87  		panic(fmt.Sprintf("invalid event type: %T", v))
    88  	}
    89  	return event
    90  }
    91  
    92  // ControlEvent creates a new control event
    93  func ControlEvent(v interface{}) *Event {
    94  	event := NewEvent(v)
    95  	event.Control = true
    96  	return event
    97  }
    98  
    99  // String returns the string representation of the event
   100  func (e *Event) String() string {
   101  	switch e.Type {
   102  	case EventTypeNode:
   103  		return fmt.Sprintf("<node-event> id: %s up: %t", e.Node.ID().TerminalString(), e.Node.Up())
   104  	case EventTypeConn:
   105  		return fmt.Sprintf("<conn-event> nodes: %s->%s up: %t", e.Conn.One.TerminalString(), e.Conn.Other.TerminalString(), e.Conn.Up)
   106  	case EventTypeMsg:
   107  		return fmt.Sprintf("<msg-event> nodes: %s->%s proto: %s, code: %d, received: %t", e.Msg.One.TerminalString(), e.Msg.Other.TerminalString(), e.Msg.Protocol, e.Msg.Code, e.Msg.Received)
   108  	default:
   109  		return ""
   110  	}
   111  }