github.com/amazechain/amc@v0.1.3/internal/network/package.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package network 18 19 import ( 20 "bytes" 21 "github.com/amazechain/amc/common/message" 22 "github.com/libp2p/go-libp2p/core/peer" 23 "io" 24 ) 25 26 const ( 27 // Maximum payload size in bytes (256MiB - 1B). 28 MaxPayloadSize = (1 << (4 * 7)) - 1 29 ) 30 31 type P2PMessage struct { 32 MsgType message.MessageType 33 Payload []byte 34 id peer.ID 35 } 36 37 func (m *P2PMessage) Type() message.MessageType { 38 return m.MsgType 39 } 40 41 func (m *P2PMessage) Encode() ([]byte, error) { 42 return m.Payload, nil 43 } 44 45 func (m *P2PMessage) Decode(t message.MessageType, payload []byte) error { 46 m.MsgType = t 47 m.Payload = payload 48 return nil 49 } 50 51 func (m *P2PMessage) Peer() peer.ID { 52 return m.id 53 } 54 55 func (m *P2PMessage) Broadcast() bool { 56 return false 57 } 58 59 type Message struct { 60 msgType message.MessageType 61 payload []byte 62 } 63 64 type Header struct { 65 DupFlag, Retain bool 66 } 67 68 func (hdr *Header) Encode(w io.Writer, msgType message.MessageType, remainingLength int32) error { 69 buf := new(bytes.Buffer) 70 err := hdr.encodeInto(buf, msgType, remainingLength) 71 if err != nil { 72 return err 73 } 74 _, err = w.Write(buf.Bytes()) 75 return err 76 } 77 78 func (hdr *Header) encodeInto(buf *bytes.Buffer, msgType message.MessageType, remainingLength int32) error { 79 if !msgType.IsValid() { 80 return badMsgTypeError 81 } 82 83 val := byte(msgType) << 4 84 val |= (boolToByte(hdr.DupFlag) << 3) 85 val |= boolToByte(hdr.Retain) 86 buf.WriteByte(val) 87 encodeLength(remainingLength, buf) 88 return nil 89 } 90 91 func (hdr *Header) Decode(r io.Reader) (msgType message.MessageType, remainingLength int32, err error) { 92 defer func() { 93 err = recoverError(err, recover()) 94 }() 95 96 var buf [1]byte 97 98 if _, err = io.ReadFull(r, buf[:]); err != nil { 99 return 100 } 101 102 byte1 := buf[0] 103 msgType = message.MessageType(byte1 & 0xF0 >> 4) 104 105 *hdr = Header{ 106 DupFlag: byte1&0x08 > 0, 107 Retain: byte1&0x01 > 0, 108 } 109 110 remainingLength = decodeLength(r) 111 112 return 113 } 114 115 func boolToByte(val bool) byte { 116 if val { 117 return byte(1) 118 } 119 return byte(0) 120 } 121 122 func decodeLength(r io.Reader) int32 { 123 var v int32 124 var buf [1]byte 125 var shift uint 126 for i := 0; i < 4; i++ { 127 if _, err := io.ReadFull(r, buf[:]); err != nil { 128 raiseError(err) 129 } 130 131 b := buf[0] 132 v |= int32(b&0x7f) << shift 133 134 if b&0x80 == 0 { 135 return v 136 } 137 shift += 7 138 } 139 140 raiseError(badLengthEncodingError) 141 panic("unreachable") 142 } 143 144 func encodeLength(length int32, buf *bytes.Buffer) { 145 if length == 0 { 146 buf.WriteByte(0) 147 return 148 } 149 for length > 0 { 150 digit := length & 0x7f 151 length = length >> 7 152 if length > 0 { 153 digit = digit | 0x80 154 } 155 buf.WriteByte(byte(digit)) 156 } 157 }