github.com/jimmyx0x/go-ethereum@v1.10.28/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  		event.Node = v.copy()
    77  	case *Conn:
    78  		event.Type = EventTypeConn
    79  		conn := *v
    80  		event.Conn = &conn
    81  	case *Msg:
    82  		event.Type = EventTypeMsg
    83  		msg := *v
    84  		event.Msg = &msg
    85  	default:
    86  		panic(fmt.Sprintf("invalid event type: %T", v))
    87  	}
    88  	return event
    89  }
    90  
    91  // ControlEvent creates a new control event
    92  func ControlEvent(v interface{}) *Event {
    93  	event := NewEvent(v)
    94  	event.Control = true
    95  	return event
    96  }
    97  
    98  // String returns the string representation of the event
    99  func (e *Event) String() string {
   100  	switch e.Type {
   101  	case EventTypeNode:
   102  		return fmt.Sprintf("<node-event> id: %s up: %t", e.Node.ID().TerminalString(), e.Node.Up())
   103  	case EventTypeConn:
   104  		return fmt.Sprintf("<conn-event> nodes: %s->%s up: %t", e.Conn.One.TerminalString(), e.Conn.Other.TerminalString(), e.Conn.Up)
   105  	case EventTypeMsg:
   106  		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)
   107  	default:
   108  		return ""
   109  	}
   110  }