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  }