github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/p2p/simulations/events.go (about)

     1  //  Copyright 2018 The go-ethereum Authors
     2  //  Copyright 2019 The go-aigar Authors
     3  //  This file is part of the go-aigar library.
     4  //
     5  //  The go-aigar library is free software: you can redistribute it and/or modify
     6  //  it under the terms of the GNU Lesser General Public License as published by
     7  //  the Free Software Foundation, either version 3 of the License, or
     8  //  (at your option) any later version.
     9  //
    10  //  The go-aigar library is distributed in the hope that it will be useful,
    11  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  //  GNU Lesser General Public License for more details.
    14  //
    15  //  You should have received a copy of the GNU Lesser General Public License
    16  //  along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package simulations
    19  
    20  import (
    21  	"fmt"
    22  	"time"
    23  )
    24  
    25  // EventType is the type of event emitted by a simulation network
    26  type EventType string
    27  
    28  const (
    29  	// EventTypeNode is the type of event emitted when a node is either
    30  	// created, started or stopped
    31  	EventTypeNode EventType = "node"
    32  
    33  	// EventTypeConn is the type of event emitted when a connection is
    34  	// is either established or dropped between two nodes
    35  	EventTypeConn EventType = "conn"
    36  
    37  	// EventTypeMsg is the type of event emitted when a p2p message it
    38  	// sent between two nodes
    39  	EventTypeMsg EventType = "msg"
    40  )
    41  
    42  // Event is an event emitted by a simulation network
    43  type Event struct {
    44  	// Type is the type of the event
    45  	Type EventType `json:"type"`
    46  
    47  	// Time is the time the event happened
    48  	Time time.Time `json:"time"`
    49  
    50  	// Control indicates whether the event is the result of a controlled
    51  	// action in the network
    52  	Control bool `json:"control"`
    53  
    54  	// Node is set if the type is EventTypeNode
    55  	Node *Node `json:"node,omitempty"`
    56  
    57  	// Conn is set if the type is EventTypeConn
    58  	Conn *Conn `json:"conn,omitempty"`
    59  
    60  	// Msg is set if the type is EventTypeMsg
    61  	Msg *Msg `json:"msg,omitempty"`
    62  
    63  	//Optionally provide data (currently for simulation frontends only)
    64  	Data interface{} `json:"data"`
    65  }
    66  
    67  // NewEvent creates a new event for the given object which should be either a
    68  // Node, Conn or Msg.
    69  //
    70  // The object is copied so that the event represents the state of the object
    71  // when NewEvent is called.
    72  func NewEvent(v interface{}) *Event {
    73  	event := &Event{Time: time.Now()}
    74  	switch v := v.(type) {
    75  	case *Node:
    76  		event.Type = EventTypeNode
    77  		node := *v
    78  		event.Node = &node
    79  	case *Conn:
    80  		event.Type = EventTypeConn
    81  		conn := *v
    82  		event.Conn = &conn
    83  	case *Msg:
    84  		event.Type = EventTypeMsg
    85  		msg := *v
    86  		event.Msg = &msg
    87  	default:
    88  		panic(fmt.Sprintf("invalid event type: %T", v))
    89  	}
    90  	return event
    91  }
    92  
    93  // ControlEvent creates a new control event
    94  func ControlEvent(v interface{}) *Event {
    95  	event := NewEvent(v)
    96  	event.Control = true
    97  	return event
    98  }
    99  
   100  // String returns the string representation of the event
   101  func (e *Event) String() string {
   102  	switch e.Type {
   103  	case EventTypeNode:
   104  		return fmt.Sprintf("<node-event> id: %s up: %t", e.Node.ID().TerminalString(), e.Node.Up())
   105  	case EventTypeConn:
   106  		return fmt.Sprintf("<conn-event> nodes: %s->%s up: %t", e.Conn.One.TerminalString(), e.Conn.Other.TerminalString(), e.Conn.Up)
   107  	case EventTypeMsg:
   108  		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)
   109  	default:
   110  		return ""
   111  	}
   112  }