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 }