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 }