mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-28 21:51:22 +00:00
95 lines
2.0 KiB
Go
95 lines
2.0 KiB
Go
package p2p
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
|
|
. "github.com/tendermint/tendermint/binary"
|
|
)
|
|
|
|
/*
|
|
A Message is anything that can be serialized.
|
|
The resulting serialized bytes of Message don't contain type information,
|
|
so messages are typically wrapped in a TypedMessage before put in the wire.
|
|
*/
|
|
type Message interface {
|
|
Binary
|
|
}
|
|
|
|
/*
|
|
A TypedMessage extends a Message with a single byte of type information.
|
|
When deserializing a message from the wire, a switch statement is needed
|
|
to dispatch to the correct constructor, typically named "ReadXXXMessage".
|
|
*/
|
|
type TypedMessage struct {
|
|
Type Byte
|
|
Message Message
|
|
}
|
|
|
|
func (tm TypedMessage) WriteTo(w io.Writer) (n int64, err error) {
|
|
n, err = WriteTo(tm.Type, w, n, err)
|
|
n, err = WriteTo(tm.Message, w, n, err)
|
|
return
|
|
}
|
|
|
|
func (tm TypedMessage) String() string {
|
|
return fmt.Sprintf("0x%X⋺%v", tm.Type, tm.Message)
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/*
|
|
Packet encapsulates a ByteSlice on a Channel.
|
|
Typically the Bytes are the serialized form of a TypedMessage.
|
|
*/
|
|
type Packet struct {
|
|
Channel String
|
|
Bytes ByteSlice
|
|
// Hash
|
|
}
|
|
|
|
func NewPacket(chName String, msg Binary) Packet {
|
|
msgBytes := BinaryBytes(msg)
|
|
return Packet{
|
|
Channel: chName,
|
|
Bytes: msgBytes,
|
|
}
|
|
}
|
|
|
|
func (p Packet) WriteTo(w io.Writer) (n int64, err error) {
|
|
n, err = WriteTo(p.Channel, w, n, err)
|
|
n, err = WriteTo(p.Bytes, w, n, err)
|
|
return
|
|
}
|
|
|
|
func (p Packet) Reader() io.Reader {
|
|
return bytes.NewReader(p.Bytes)
|
|
}
|
|
|
|
func (p Packet) String() string {
|
|
return fmt.Sprintf("%v:%X", p.Channel, p.Bytes)
|
|
}
|
|
|
|
func ReadPacketSafe(r io.Reader) (pkt Packet, err error) {
|
|
chName, err := ReadStringSafe(r)
|
|
if err != nil {
|
|
return
|
|
}
|
|
// TODO: packet length sanity check.
|
|
bytes, err := ReadByteSliceSafe(r)
|
|
if err != nil {
|
|
return
|
|
}
|
|
return Packet{Channel: chName, Bytes: bytes}, nil
|
|
}
|
|
|
|
/*
|
|
InboundPacket extends Packet with fields relevant to inbound packets.
|
|
*/
|
|
type InboundPacket struct {
|
|
Peer *Peer
|
|
Time Time
|
|
Packet
|
|
}
|