github.com/mandrigin/go-ethereum@v1.7.4-0.20180116162341-02aeb3d76652/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  
    63  // NewEvent creates a new event for the given object which should be either a
    64  // Node, Conn or Msg.
    65  //
    66  // The object is copied so that the event represents the state of the object
    67  // when NewEvent is called.
    68  func NewEvent(v interface{}) *Event {
    69  	event := &Event{Time: time.Now()}
    70  	switch v := v.(type) {
    71  	case *Node:
    72  		event.Type = EventTypeNode
    73  		node := *v
    74  		event.Node = &node
    75  	case *Conn:
    76  		event.Type = EventTypeConn
    77  		conn := *v
    78  		event.Conn = &conn
    79  	case *Msg:
    80  		event.Type = EventTypeMsg
    81  		msg := *v
    82  		event.Msg = &msg
    83  	default:
    84  		panic(fmt.Sprintf("invalid event type: %T", v))
    85  	}
    86  	return event
    87  }
    88  
    89  // ControlEvent creates a new control event
    90  func ControlEvent(v interface{}) *Event {
    91  	event := NewEvent(v)
    92  	event.Control = true
    93  	return event
    94  }
    95  
    96  // String returns the string representation of the event
    97  func (e *Event) String() string {
    98  	switch e.Type {
    99  	case EventTypeNode:
   100  		return fmt.Sprintf("<node-event> id: %s up: %t", e.Node.ID().TerminalString(), e.Node.Up)
   101  	case EventTypeConn:
   102  		return fmt.Sprintf("<conn-event> nodes: %s->%s up: %t", e.Conn.One.TerminalString(), e.Conn.Other.TerminalString(), e.Conn.Up)
   103  	case EventTypeMsg:
   104  		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)
   105  	default:
   106  		return ""
   107  	}
   108  }