github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/network/capability/capability.go (about) 1 package capability 2 3 import ( 4 "errors" 5 6 "github.com/nspcc-dev/neo-go/pkg/io" 7 ) 8 9 // MaxCapabilities is the maximum number of capabilities per payload. 10 const MaxCapabilities = 32 11 12 // Capabilities is a list of Capability. 13 type Capabilities []Capability 14 15 // DecodeBinary implements io.Serializable. 16 func (cs *Capabilities) DecodeBinary(br *io.BinReader) { 17 br.ReadArray(cs, MaxCapabilities) 18 br.Err = cs.checkUniqueCapabilities() 19 } 20 21 // EncodeBinary implements io.Serializable. 22 func (cs *Capabilities) EncodeBinary(br *io.BinWriter) { 23 br.WriteArray(*cs) 24 } 25 26 // checkUniqueCapabilities checks whether payload capabilities have a unique type. 27 func (cs Capabilities) checkUniqueCapabilities() error { 28 err := errors.New("capabilities with the same type are not allowed") 29 var isFullNode, isTCP, isWS bool 30 for _, cap := range cs { 31 switch cap.Type { 32 case FullNode: 33 if isFullNode { 34 return err 35 } 36 isFullNode = true 37 case TCPServer: 38 if isTCP { 39 return err 40 } 41 isTCP = true 42 case WSServer: 43 if isWS { 44 return err 45 } 46 isWS = true 47 } 48 } 49 return nil 50 } 51 52 // Capability describes a network service available for the node. 53 type Capability struct { 54 Type Type 55 Data io.Serializable 56 } 57 58 // DecodeBinary implements io.Serializable. 59 func (c *Capability) DecodeBinary(br *io.BinReader) { 60 c.Type = Type(br.ReadB()) 61 switch c.Type { 62 case FullNode: 63 c.Data = &Node{} 64 case TCPServer, WSServer: 65 c.Data = &Server{} 66 default: 67 br.Err = errors.New("unknown node capability type") 68 return 69 } 70 c.Data.DecodeBinary(br) 71 } 72 73 // EncodeBinary implements io.Serializable. 74 func (c *Capability) EncodeBinary(bw *io.BinWriter) { 75 if c.Data == nil { 76 bw.Err = errors.New("capability has no data") 77 return 78 } 79 bw.WriteB(byte(c.Type)) 80 c.Data.EncodeBinary(bw) 81 } 82 83 // Node represents full node capability with a start height. 84 type Node struct { 85 StartHeight uint32 86 } 87 88 // DecodeBinary implements io.Serializable. 89 func (n *Node) DecodeBinary(br *io.BinReader) { 90 n.StartHeight = br.ReadU32LE() 91 } 92 93 // EncodeBinary implements io.Serializable. 94 func (n *Node) EncodeBinary(bw *io.BinWriter) { 95 bw.WriteU32LE(n.StartHeight) 96 } 97 98 // Server represents TCP or WS server capability with a port. 99 type Server struct { 100 // Port is the port this server is listening on. 101 Port uint16 102 } 103 104 // DecodeBinary implements io.Serializable. 105 func (s *Server) DecodeBinary(br *io.BinReader) { 106 s.Port = br.ReadU16LE() 107 } 108 109 // EncodeBinary implements io.Serializable. 110 func (s *Server) EncodeBinary(bw *io.BinWriter) { 111 bw.WriteU16LE(s.Port) 112 }