mirror of
https://github.com/luxfi/node.git
synced 2026-07-27 03:39:39 +00:00
87 lines
1.9 KiB
Go
87 lines
1.9 KiB
Go
//go:build grpc
|
|
|
|
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package message
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
|
|
"github.com/luxfi/ids"
|
|
|
|
pb "github.com/luxfi/node/proto/pb/message"
|
|
)
|
|
|
|
var (
|
|
_ Message = (*Tx)(nil)
|
|
|
|
ErrUnexpectedCodecVersion = errors.New("unexpected codec version")
|
|
errUnknownMessageType = errors.New("unknown message type")
|
|
)
|
|
|
|
type Message interface {
|
|
// Handle this message with the correct message handler
|
|
Handle(handler Handler, nodeID ids.NodeID, requestID uint32) error
|
|
|
|
// initialize should be called whenever a message is built or parsed
|
|
initialize([]byte)
|
|
|
|
// Bytes returns the binary representation of this message
|
|
//
|
|
// Bytes should only be called after being initialized
|
|
Bytes() []byte
|
|
}
|
|
|
|
type message []byte
|
|
|
|
func (m *message) initialize(bytes []byte) {
|
|
*m = bytes
|
|
}
|
|
|
|
func (m *message) Bytes() []byte {
|
|
return *m
|
|
}
|
|
|
|
func Parse(bytes []byte) (Message, error) {
|
|
var (
|
|
msg Message
|
|
protoMsg pb.Message
|
|
)
|
|
|
|
if err := proto.Unmarshal(bytes, &protoMsg); err == nil {
|
|
// This message was encoded with proto.
|
|
switch m := protoMsg.GetMessage().(type) {
|
|
case *pb.Message_Tx:
|
|
msg = &Tx{
|
|
Tx: m.Tx.Tx,
|
|
}
|
|
default:
|
|
return nil, fmt.Errorf("%w: %T", errUnknownMessageType, protoMsg.GetMessage())
|
|
}
|
|
} else {
|
|
// This message wasn't encoded with proto.
|
|
// It must have been encoded with node's codec.
|
|
// Legacy codec fallback for nodes older than v1.11.0 that do not
|
|
// support proto encoding.
|
|
version, err := c.Unmarshal(bytes, &msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if version != codecVersion {
|
|
return nil, ErrUnexpectedCodecVersion
|
|
}
|
|
}
|
|
msg.initialize(bytes)
|
|
return msg, nil
|
|
}
|
|
|
|
func Build(msg Message) ([]byte, error) {
|
|
bytes, err := c.Marshal(codecVersion, &msg)
|
|
msg.initialize(bytes)
|
|
return bytes, err
|
|
}
|