github.com/aquanetwork/aquachain@v1.7.8/p2p/simulations/events.go (about) 1 // Copyright 2017 The aquachain Authors 2 // This file is part of the aquachain library. 3 // 4 // The aquachain 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 aquachain 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 aquachain 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 }