mirror of
https://github.com/luxfi/node.git
synced 2026-07-27 03:39:39 +00:00
clean: squash history (binaries stripped via filter-repo)
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
//go:build grpc
|
||||
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import "github.com/luxfi/node/proto/p2p"
|
||||
|
||||
// newMessageBFT creates a BFT message wrapper (gRPC version - uses Simplex)
|
||||
func newMessageBFT(msg *p2p.BFT) *p2p.Message_BFT {
|
||||
return &p2p.Message_BFT{Simplex: msg}
|
||||
}
|
||||
|
||||
// extractBFT extracts the BFT message from the wrapper (gRPC version - uses Simplex)
|
||||
func extractBFT(msg *p2p.Message_BFT) *p2p.BFT {
|
||||
return msg.Simplex
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
//go:build !grpc
|
||||
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import "github.com/luxfi/node/proto/p2p"
|
||||
|
||||
// newMessageBFT creates a BFT message wrapper (ZAP version)
|
||||
func newMessageBFT(msg *p2p.BFT) *p2p.Message_BFT {
|
||||
return &p2p.Message_BFT{BFT: msg}
|
||||
}
|
||||
|
||||
// extractBFT extracts the BFT message from the wrapper (ZAP version)
|
||||
func extractBFT(msg *p2p.Message_BFT) *p2p.BFT {
|
||||
return msg.BFT
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
// Codec defines the wire format encoding interface for P2P messages.
|
||||
// Implementations are selected via build tags (proto vs zap).
|
||||
type Codec interface {
|
||||
Marshal(msg *P2PMessage) ([]byte, error)
|
||||
Unmarshal(data []byte, msg *P2PMessage) error
|
||||
Size(msg *P2PMessage) int
|
||||
}
|
||||
|
||||
// P2PMessage is the top-level message container used by the codec.
|
||||
// It wraps the inner message type for encoding/decoding.
|
||||
type P2PMessage struct {
|
||||
inner interface{}
|
||||
}
|
||||
|
||||
// SetInner sets the inner message
|
||||
func (m *P2PMessage) SetInner(v interface{}) {
|
||||
m.inner = v
|
||||
}
|
||||
|
||||
// Inner returns the inner message
|
||||
func (m *P2PMessage) Inner() interface{} {
|
||||
return m.inner
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/metric"
|
||||
compression "github.com/luxfi/compress"
|
||||
)
|
||||
|
||||
var _ Creator = (*creator)(nil)
|
||||
|
||||
type Creator interface {
|
||||
OutboundMsgBuilder
|
||||
InboundMsgBuilder
|
||||
}
|
||||
|
||||
type creator struct {
|
||||
OutboundMsgBuilder
|
||||
InboundMsgBuilder
|
||||
}
|
||||
|
||||
func NewCreator(
|
||||
metrics metric.Registerer,
|
||||
compressionType compression.Type,
|
||||
maxMessageTimeout time.Duration,
|
||||
) (Creator, error) {
|
||||
builder, err := newMsgBuilder(
|
||||
metrics,
|
||||
maxMessageTimeout,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &creator{
|
||||
OutboundMsgBuilder: newOutboundBuilder(compressionType, builder),
|
||||
InboundMsgBuilder: newInboundBuilder(builder),
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
)
|
||||
|
||||
var (
|
||||
errMissingField = errors.New("message missing field")
|
||||
|
||||
_ chainIDGetter = (*p2p.GetStateSummaryFrontier)(nil)
|
||||
_ chainIDGetter = (*p2p.StateSummaryFrontier)(nil)
|
||||
_ chainIDGetter = (*p2p.GetAcceptedStateSummary)(nil)
|
||||
_ chainIDGetter = (*p2p.AcceptedStateSummary)(nil)
|
||||
_ chainIDGetter = (*p2p.GetAcceptedFrontier)(nil)
|
||||
_ chainIDGetter = (*p2p.AcceptedFrontier)(nil)
|
||||
_ chainIDGetter = (*p2p.GetAccepted)(nil)
|
||||
_ chainIDGetter = (*p2p.Accepted)(nil)
|
||||
_ chainIDGetter = (*p2p.GetAncestors)(nil)
|
||||
_ chainIDGetter = (*p2p.Ancestors)(nil)
|
||||
_ chainIDGetter = (*p2p.Get)(nil)
|
||||
_ chainIDGetter = (*p2p.Put)(nil)
|
||||
_ chainIDGetter = (*p2p.PushQuery)(nil)
|
||||
_ chainIDGetter = (*p2p.PullQuery)(nil)
|
||||
_ chainIDGetter = (*p2p.Chits)(nil)
|
||||
_ chainIDGetter = (*p2p.Request)(nil)
|
||||
_ chainIDGetter = (*p2p.Response)(nil)
|
||||
_ chainIDGetter = (*p2p.Gossip)(nil)
|
||||
_ chainIDGetter = (*p2p.BFT)(nil)
|
||||
|
||||
_ requestIDGetter = (*p2p.GetStateSummaryFrontier)(nil)
|
||||
_ requestIDGetter = (*p2p.StateSummaryFrontier)(nil)
|
||||
_ requestIDGetter = (*p2p.GetAcceptedStateSummary)(nil)
|
||||
_ requestIDGetter = (*p2p.AcceptedStateSummary)(nil)
|
||||
_ requestIDGetter = (*p2p.GetAcceptedFrontier)(nil)
|
||||
_ requestIDGetter = (*p2p.AcceptedFrontier)(nil)
|
||||
_ requestIDGetter = (*p2p.GetAccepted)(nil)
|
||||
_ requestIDGetter = (*p2p.Accepted)(nil)
|
||||
_ requestIDGetter = (*p2p.GetAncestors)(nil)
|
||||
_ requestIDGetter = (*p2p.Ancestors)(nil)
|
||||
_ requestIDGetter = (*p2p.Get)(nil)
|
||||
_ requestIDGetter = (*p2p.Put)(nil)
|
||||
_ requestIDGetter = (*p2p.PushQuery)(nil)
|
||||
_ requestIDGetter = (*p2p.PullQuery)(nil)
|
||||
_ requestIDGetter = (*p2p.Chits)(nil)
|
||||
_ requestIDGetter = (*p2p.Request)(nil)
|
||||
_ requestIDGetter = (*p2p.Response)(nil)
|
||||
|
||||
_ engineTypeGetter = (*p2p.GetAncestors)(nil)
|
||||
|
||||
_ deadlineGetter = (*p2p.GetStateSummaryFrontier)(nil)
|
||||
_ deadlineGetter = (*p2p.GetAcceptedStateSummary)(nil)
|
||||
_ deadlineGetter = (*p2p.GetAcceptedFrontier)(nil)
|
||||
_ deadlineGetter = (*p2p.GetAccepted)(nil)
|
||||
_ deadlineGetter = (*p2p.GetAncestors)(nil)
|
||||
_ deadlineGetter = (*p2p.Get)(nil)
|
||||
_ deadlineGetter = (*p2p.PushQuery)(nil)
|
||||
_ deadlineGetter = (*p2p.PullQuery)(nil)
|
||||
_ deadlineGetter = (*p2p.Request)(nil)
|
||||
)
|
||||
|
||||
type chainIDGetter interface {
|
||||
GetChainId() []byte
|
||||
}
|
||||
|
||||
func GetChainID(m any) (ids.ID, error) {
|
||||
msg, ok := m.(chainIDGetter)
|
||||
if !ok {
|
||||
return ids.Empty, errMissingField
|
||||
}
|
||||
chainIDBytes := msg.GetChainId()
|
||||
return ids.ToID(chainIDBytes)
|
||||
}
|
||||
|
||||
type requestIDGetter interface {
|
||||
GetRequestId() uint32
|
||||
}
|
||||
|
||||
func GetRequestID(m any) (uint32, bool) {
|
||||
if msg, ok := m.(requestIDGetter); ok {
|
||||
return msg.GetRequestId(), true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
type engineTypeGetter interface {
|
||||
GetEngineType() p2p.EngineType
|
||||
}
|
||||
|
||||
func GetEngineType(m any) (p2p.EngineType, bool) {
|
||||
msg, ok := m.(engineTypeGetter)
|
||||
if !ok {
|
||||
return p2p.EngineType_ENGINE_TYPE_UNSPECIFIED, false
|
||||
}
|
||||
return msg.GetEngineType(), true
|
||||
}
|
||||
|
||||
type deadlineGetter interface {
|
||||
GetDeadline() uint64
|
||||
}
|
||||
|
||||
func GetDeadline(m any) (time.Duration, bool) {
|
||||
msg, ok := m.(deadlineGetter)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
deadline := msg.GetDeadline()
|
||||
return time.Duration(deadline), true
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
"github.com/luxfi/timer/mockable"
|
||||
)
|
||||
|
||||
var _ InboundMsgBuilder = (*inMsgBuilder)(nil)
|
||||
|
||||
type InboundMsgBuilder interface {
|
||||
// Parse reads given bytes as InboundMessage
|
||||
Parse(
|
||||
bytes []byte,
|
||||
nodeID ids.NodeID,
|
||||
onFinishedHandling func(),
|
||||
) (InboundMessage, error)
|
||||
}
|
||||
|
||||
type inMsgBuilder struct {
|
||||
builder *msgBuilder
|
||||
}
|
||||
|
||||
func newInboundBuilder(builder *msgBuilder) InboundMsgBuilder {
|
||||
return &inMsgBuilder{
|
||||
builder: builder,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *inMsgBuilder) Parse(bytes []byte, nodeID ids.NodeID, onFinishedHandling func()) (InboundMessage, error) {
|
||||
return b.builder.parseInbound(bytes, nodeID, onFinishedHandling)
|
||||
}
|
||||
|
||||
func InboundGetStateSummaryFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetStateSummaryFrontierOp,
|
||||
message: &p2p.GetStateSummaryFrontier{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
},
|
||||
expiration: time.Now().Add(deadline),
|
||||
}
|
||||
}
|
||||
|
||||
func InboundStateSummaryFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
summary []byte,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: StateSummaryFrontierOp,
|
||||
message: &p2p.StateSummaryFrontier{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Summary: summary,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
func InboundGetAcceptedStateSummary(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
heights []uint64,
|
||||
deadline time.Duration,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetAcceptedStateSummaryOp,
|
||||
message: &p2p.GetAcceptedStateSummary{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
Heights: heights,
|
||||
},
|
||||
expiration: time.Now().Add(deadline),
|
||||
}
|
||||
}
|
||||
|
||||
func InboundAcceptedStateSummary(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
summaryIDs []ids.ID,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
summaryIDBytes := make([][]byte, len(summaryIDs))
|
||||
encodeIDs(summaryIDs, summaryIDBytes)
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: AcceptedStateSummaryOp,
|
||||
message: &p2p.AcceptedStateSummary{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
SummaryIds: summaryIDBytes,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
func InboundGetAcceptedFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetAcceptedFrontierOp,
|
||||
message: &p2p.GetAcceptedFrontier{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
},
|
||||
expiration: time.Now().Add(deadline),
|
||||
}
|
||||
}
|
||||
|
||||
func InboundAcceptedFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
containerID ids.ID,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: AcceptedFrontierOp,
|
||||
message: &p2p.AcceptedFrontier{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
ContainerId: containerID[:],
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
func InboundGetAccepted(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerIDs []ids.ID,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
containerIDBytes := make([][]byte, len(containerIDs))
|
||||
encodeIDs(containerIDs, containerIDBytes)
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetAcceptedOp,
|
||||
message: &p2p.GetAccepted{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
ContainerIds: containerIDBytes,
|
||||
},
|
||||
expiration: time.Now().Add(deadline),
|
||||
}
|
||||
}
|
||||
|
||||
func InboundAccepted(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
containerIDs []ids.ID,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
containerIDBytes := make([][]byte, len(containerIDs))
|
||||
encodeIDs(containerIDs, containerIDBytes)
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: AcceptedOp,
|
||||
message: &p2p.Accepted{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
ContainerIds: containerIDBytes,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
func InboundPushQuery(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
container []byte,
|
||||
requestedHeight uint64,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: PushQueryOp,
|
||||
message: &p2p.PushQuery{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
Container: container,
|
||||
RequestedHeight: requestedHeight,
|
||||
},
|
||||
expiration: time.Now().Add(deadline),
|
||||
}
|
||||
}
|
||||
|
||||
func InboundPullQuery(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerID ids.ID,
|
||||
requestedHeight uint64,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: PullQueryOp,
|
||||
message: &p2p.PullQuery{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
ContainerId: containerID[:],
|
||||
RequestedHeight: requestedHeight,
|
||||
},
|
||||
expiration: time.Now().Add(deadline),
|
||||
}
|
||||
}
|
||||
|
||||
func InboundChits(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
preferredID ids.ID,
|
||||
preferredIDAtHeight ids.ID,
|
||||
acceptedID ids.ID,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: QbitOp,
|
||||
message: &p2p.Chits{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
PreferredId: preferredID[:],
|
||||
PreferredIdAtHeight: preferredIDAtHeight[:],
|
||||
AcceptedId: acceptedID[:],
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
func InboundRequest(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
msg []byte,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: RequestOp,
|
||||
message: &p2p.Request{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
AppBytes: msg,
|
||||
},
|
||||
expiration: time.Now().Add(deadline),
|
||||
}
|
||||
}
|
||||
|
||||
func InboundError(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
errorCode int32,
|
||||
errorMessage string,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: ErrorOp,
|
||||
message: &p2p.Error{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
ErrorCode: errorCode,
|
||||
ErrorMessage: errorMessage,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
func InboundResponse(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
msg []byte,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: ResponseOp,
|
||||
message: &p2p.Response{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
AppBytes: msg,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
func InboundGossip(
|
||||
chainID ids.ID,
|
||||
msg []byte,
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GossipOp,
|
||||
message: &p2p.Gossip{
|
||||
ChainId: chainID[:],
|
||||
AppBytes: msg,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
// NewInboundBFTMessage creates a new InboundMessage for bft messages.
|
||||
func InboundBFTMessage(
|
||||
nodeID ids.NodeID,
|
||||
msg *p2p.BFT,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: BFTOp,
|
||||
message: msg,
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
func encodeIDs(ids []ids.ID, result [][]byte) {
|
||||
for i, id := range ids {
|
||||
result[i] = id[:]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,425 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"github.com/luxfi/metric"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
"github.com/luxfi/timer/mockable"
|
||||
compression "github.com/luxfi/compress"
|
||||
)
|
||||
|
||||
func Test_newMsgBuilder(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
|
||||
mb, err := newMsgBuilder(
|
||||
metric.NewRegistry(),
|
||||
10*time.Second,
|
||||
)
|
||||
require.NoError(err)
|
||||
require.NotNil(mb)
|
||||
}
|
||||
|
||||
func TestInboundMsgBuilder(t *testing.T) {
|
||||
var (
|
||||
chainID = ids.GenerateTestID()
|
||||
requestID uint32 = 12345
|
||||
deadline = time.Hour
|
||||
nodeID = ids.GenerateTestNodeID()
|
||||
summary = []byte{9, 8, 7}
|
||||
appBytes = []byte{1, 3, 3, 7}
|
||||
container = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
containerIDs = []ids.ID{ids.GenerateTestID(), ids.GenerateTestID()}
|
||||
requestedHeight uint64 = 999
|
||||
acceptedContainerID = ids.GenerateTestID()
|
||||
summaryIDs = []ids.ID{ids.GenerateTestID(), ids.GenerateTestID()}
|
||||
heights = []uint64{1000, 2000}
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundGetStateSummaryFrontier",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
start := time.Now()
|
||||
msg := InboundGetStateSummaryFrontier(
|
||||
chainID,
|
||||
requestID,
|
||||
deadline,
|
||||
nodeID,
|
||||
)
|
||||
end := time.Now()
|
||||
|
||||
require.Equal(GetStateSummaryFrontierOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.False(msg.Expiration().Before(start.Add(deadline)))
|
||||
require.False(end.Add(deadline).Before(msg.Expiration()))
|
||||
require.IsType(&p2p.GetStateSummaryFrontier{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.GetStateSummaryFrontier)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundStateSummaryFrontier",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
msg := InboundStateSummaryFrontier(
|
||||
chainID,
|
||||
requestID,
|
||||
summary,
|
||||
nodeID,
|
||||
)
|
||||
|
||||
require.Equal(StateSummaryFrontierOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.Equal(mockable.MaxTime, msg.Expiration())
|
||||
require.IsType(&p2p.StateSummaryFrontier{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.StateSummaryFrontier)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
require.Equal(summary, innerMsg.Summary)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundGetAcceptedStateSummary",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
start := time.Now()
|
||||
msg := InboundGetAcceptedStateSummary(
|
||||
chainID,
|
||||
requestID,
|
||||
heights,
|
||||
deadline,
|
||||
nodeID,
|
||||
)
|
||||
end := time.Now()
|
||||
|
||||
require.Equal(GetAcceptedStateSummaryOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.False(msg.Expiration().Before(start.Add(deadline)))
|
||||
require.False(end.Add(deadline).Before(msg.Expiration()))
|
||||
require.IsType(&p2p.GetAcceptedStateSummary{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.GetAcceptedStateSummary)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
require.Equal(heights, innerMsg.Heights)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundAcceptedStateSummary",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
msg := InboundAcceptedStateSummary(
|
||||
chainID,
|
||||
requestID,
|
||||
summaryIDs,
|
||||
nodeID,
|
||||
)
|
||||
|
||||
require.Equal(AcceptedStateSummaryOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.Equal(mockable.MaxTime, msg.Expiration())
|
||||
require.IsType(&p2p.AcceptedStateSummary{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.AcceptedStateSummary)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
summaryIDsBytes := make([][]byte, len(summaryIDs))
|
||||
for i, id := range summaryIDs {
|
||||
summaryIDsBytes[i] = id[:]
|
||||
}
|
||||
require.Equal(summaryIDsBytes, innerMsg.SummaryIds)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundGetAcceptedFrontier",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
start := time.Now()
|
||||
msg := InboundGetAcceptedFrontier(
|
||||
chainID,
|
||||
requestID,
|
||||
deadline,
|
||||
nodeID,
|
||||
)
|
||||
end := time.Now()
|
||||
|
||||
require.Equal(GetAcceptedFrontierOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.False(msg.Expiration().Before(start.Add(deadline)))
|
||||
require.False(end.Add(deadline).Before(msg.Expiration()))
|
||||
require.IsType(&p2p.GetAcceptedFrontier{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.GetAcceptedFrontier)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundAcceptedFrontier",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
msg := InboundAcceptedFrontier(
|
||||
chainID,
|
||||
requestID,
|
||||
containerIDs[0],
|
||||
nodeID,
|
||||
)
|
||||
|
||||
require.Equal(AcceptedFrontierOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.Equal(mockable.MaxTime, msg.Expiration())
|
||||
require.IsType(&p2p.AcceptedFrontier{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.AcceptedFrontier)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
require.Equal(containerIDs[0][:], innerMsg.ContainerId)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundGetAccepted",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
start := time.Now()
|
||||
msg := InboundGetAccepted(
|
||||
chainID,
|
||||
requestID,
|
||||
deadline,
|
||||
containerIDs,
|
||||
nodeID,
|
||||
)
|
||||
end := time.Now()
|
||||
|
||||
require.Equal(GetAcceptedOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.False(msg.Expiration().Before(start.Add(deadline)))
|
||||
require.False(end.Add(deadline).Before(msg.Expiration()))
|
||||
require.IsType(&p2p.GetAccepted{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.GetAccepted)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundAccepted",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
msg := InboundAccepted(
|
||||
chainID,
|
||||
requestID,
|
||||
containerIDs,
|
||||
nodeID,
|
||||
)
|
||||
|
||||
require.Equal(AcceptedOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.Equal(mockable.MaxTime, msg.Expiration())
|
||||
require.IsType(&p2p.Accepted{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.Accepted)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
containerIDsBytes := make([][]byte, len(containerIDs))
|
||||
for i, id := range containerIDs {
|
||||
containerIDsBytes[i] = id[:]
|
||||
}
|
||||
require.Equal(containerIDsBytes, innerMsg.ContainerIds)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundPushQuery",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
start := time.Now()
|
||||
msg := InboundPushQuery(
|
||||
chainID,
|
||||
requestID,
|
||||
deadline,
|
||||
container,
|
||||
requestedHeight,
|
||||
nodeID,
|
||||
)
|
||||
end := time.Now()
|
||||
|
||||
require.Equal(PushQueryOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.False(msg.Expiration().Before(start.Add(deadline)))
|
||||
require.False(end.Add(deadline).Before(msg.Expiration()))
|
||||
require.IsType(&p2p.PushQuery{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.PushQuery)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
require.Equal(container, innerMsg.Container)
|
||||
require.Equal(requestedHeight, innerMsg.RequestedHeight)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundPullQuery",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
start := time.Now()
|
||||
msg := InboundPullQuery(
|
||||
chainID,
|
||||
requestID,
|
||||
deadline,
|
||||
containerIDs[0],
|
||||
requestedHeight,
|
||||
nodeID,
|
||||
)
|
||||
end := time.Now()
|
||||
|
||||
require.Equal(PullQueryOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.False(msg.Expiration().Before(start.Add(deadline)))
|
||||
require.False(end.Add(deadline).Before(msg.Expiration()))
|
||||
require.IsType(&p2p.PullQuery{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.PullQuery)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
require.Equal(containerIDs[0][:], innerMsg.ContainerId)
|
||||
require.Equal(requestedHeight, innerMsg.RequestedHeight)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundChits",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
msg := InboundChits(
|
||||
chainID,
|
||||
requestID,
|
||||
containerIDs[0],
|
||||
containerIDs[1],
|
||||
acceptedContainerID,
|
||||
nodeID,
|
||||
)
|
||||
|
||||
require.Equal(QbitOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.Equal(mockable.MaxTime, msg.Expiration())
|
||||
require.IsType(&p2p.Chits{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.Chits)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
require.Equal(containerIDs[0][:], innerMsg.PreferredId)
|
||||
require.Equal(containerIDs[1][:], innerMsg.PreferredIdAtHeight)
|
||||
require.Equal(acceptedContainerID[:], innerMsg.AcceptedId)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundRequest",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
start := time.Now()
|
||||
msg := InboundRequest(
|
||||
chainID,
|
||||
requestID,
|
||||
deadline,
|
||||
appBytes,
|
||||
nodeID,
|
||||
)
|
||||
end := time.Now()
|
||||
|
||||
require.Equal(RequestOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.False(msg.Expiration().Before(start.Add(deadline)))
|
||||
require.False(end.Add(deadline).Before(msg.Expiration()))
|
||||
require.IsType(&p2p.Request{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.Request)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
require.Equal(appBytes, innerMsg.AppBytes)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InboundResponse",
|
||||
func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
msg := InboundResponse(
|
||||
chainID,
|
||||
requestID,
|
||||
appBytes,
|
||||
nodeID,
|
||||
)
|
||||
|
||||
require.Equal(ResponseOp, msg.Op())
|
||||
require.Equal(nodeID, msg.NodeID())
|
||||
require.Equal(mockable.MaxTime, msg.Expiration())
|
||||
require.IsType(&p2p.Response{}, msg.Message())
|
||||
innerMsg := msg.Message().(*p2p.Response)
|
||||
require.Equal(chainID[:], innerMsg.ChainId)
|
||||
require.Equal(requestID, innerMsg.RequestId)
|
||||
require.Equal(appBytes, innerMsg.AppBytes)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestError(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
mb, err := newMsgBuilder(
|
||||
metric.NewRegistry(),
|
||||
time.Second,
|
||||
)
|
||||
require.NoError(err)
|
||||
|
||||
nodeID := ids.GenerateTestNodeID()
|
||||
chainID := ids.GenerateTestID()
|
||||
requestID := uint32(1)
|
||||
errorCode := int32(2)
|
||||
errorMessage := "hello world"
|
||||
|
||||
want := &p2p.Message{
|
||||
Message: &p2p.Message_Error{
|
||||
Error: &p2p.Error{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
ErrorCode: errorCode,
|
||||
ErrorMessage: errorMessage,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
outMsg, err := mb.createOutbound(want, compression.TypeNone, false)
|
||||
require.NoError(err)
|
||||
|
||||
got, err := mb.parseInbound(outMsg.Bytes(), nodeID, func() {})
|
||||
require.NoError(err)
|
||||
|
||||
require.Equal(nodeID, got.NodeID())
|
||||
require.Equal(ErrorOp, got.Op())
|
||||
|
||||
msg, ok := got.Message().(*p2p.Error)
|
||||
require.True(ok)
|
||||
require.Equal(errorCode, msg.ErrorCode)
|
||||
require.Equal(errorMessage, msg.ErrorMessage)
|
||||
}
|
||||
@@ -0,0 +1,390 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
//nolint:staticcheck // proto generates interfaces that fail linting
|
||||
package message
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
"github.com/luxfi/node/version"
|
||||
"github.com/luxfi/timer/mockable"
|
||||
)
|
||||
|
||||
var (
|
||||
disconnected = &Disconnected{}
|
||||
gossipRequest = &GossipRequest{}
|
||||
|
||||
_ fmt.Stringer = (*GetStateSummaryFrontierFailed)(nil)
|
||||
_ chainIDGetter = (*GetStateSummaryFrontierFailed)(nil)
|
||||
_ requestIDGetter = (*GetStateSummaryFrontierFailed)(nil)
|
||||
|
||||
_ fmt.Stringer = (*GetAcceptedStateSummaryFailed)(nil)
|
||||
_ chainIDGetter = (*GetAcceptedStateSummaryFailed)(nil)
|
||||
_ requestIDGetter = (*GetAcceptedStateSummaryFailed)(nil)
|
||||
|
||||
_ fmt.Stringer = (*GetAcceptedFrontierFailed)(nil)
|
||||
_ chainIDGetter = (*GetAcceptedFrontierFailed)(nil)
|
||||
_ requestIDGetter = (*GetAcceptedFrontierFailed)(nil)
|
||||
|
||||
_ fmt.Stringer = (*GetAcceptedFailed)(nil)
|
||||
_ chainIDGetter = (*GetAcceptedFailed)(nil)
|
||||
_ requestIDGetter = (*GetAcceptedFailed)(nil)
|
||||
|
||||
_ fmt.Stringer = (*GetAncestorsFailed)(nil)
|
||||
_ chainIDGetter = (*GetAncestorsFailed)(nil)
|
||||
_ requestIDGetter = (*GetAncestorsFailed)(nil)
|
||||
_ engineTypeGetter = (*GetAncestorsFailed)(nil)
|
||||
|
||||
_ fmt.Stringer = (*GetFailed)(nil)
|
||||
_ chainIDGetter = (*GetFailed)(nil)
|
||||
_ requestIDGetter = (*GetFailed)(nil)
|
||||
|
||||
_ fmt.Stringer = (*QueryFailed)(nil)
|
||||
_ chainIDGetter = (*QueryFailed)(nil)
|
||||
_ requestIDGetter = (*QueryFailed)(nil)
|
||||
|
||||
_ fmt.Stringer = (*Disconnected)(nil)
|
||||
|
||||
_ fmt.Stringer = (*GossipRequest)(nil)
|
||||
)
|
||||
|
||||
type GetStateSummaryFrontierFailed struct {
|
||||
ChainID ids.ID `json:"chain_id,omitempty"`
|
||||
RequestID uint32 `json:"request_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetStateSummaryFrontierFailed) String() string {
|
||||
return fmt.Sprintf(
|
||||
"ChainID: %s RequestID: %d",
|
||||
m.ChainID, m.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
func (m *GetStateSummaryFrontierFailed) GetChainId() []byte {
|
||||
return m.ChainID[:]
|
||||
}
|
||||
|
||||
func (m *GetStateSummaryFrontierFailed) GetRequestId() uint32 {
|
||||
return m.RequestID
|
||||
}
|
||||
|
||||
func InternalGetStateSummaryFrontierFailed(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetStateSummaryFrontierFailedOp,
|
||||
message: &GetStateSummaryFrontierFailed{
|
||||
ChainID: chainID,
|
||||
RequestID: requestID,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type GetAcceptedStateSummaryFailed struct {
|
||||
ChainID ids.ID `json:"chain_id,omitempty"`
|
||||
RequestID uint32 `json:"request_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetAcceptedStateSummaryFailed) String() string {
|
||||
return fmt.Sprintf(
|
||||
"ChainID: %s RequestID: %d",
|
||||
m.ChainID, m.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
func (m *GetAcceptedStateSummaryFailed) GetChainId() []byte {
|
||||
return m.ChainID[:]
|
||||
}
|
||||
|
||||
func (m *GetAcceptedStateSummaryFailed) GetRequestId() uint32 {
|
||||
return m.RequestID
|
||||
}
|
||||
|
||||
func InternalGetAcceptedStateSummaryFailed(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetAcceptedStateSummaryFailedOp,
|
||||
message: &GetAcceptedStateSummaryFailed{
|
||||
ChainID: chainID,
|
||||
RequestID: requestID,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type GetAcceptedFrontierFailed struct {
|
||||
ChainID ids.ID `json:"chain_id,omitempty"`
|
||||
RequestID uint32 `json:"request_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetAcceptedFrontierFailed) String() string {
|
||||
return fmt.Sprintf(
|
||||
"ChainID: %s RequestID: %d",
|
||||
m.ChainID, m.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
func (m *GetAcceptedFrontierFailed) GetChainId() []byte {
|
||||
return m.ChainID[:]
|
||||
}
|
||||
|
||||
func (m *GetAcceptedFrontierFailed) GetRequestId() uint32 {
|
||||
return m.RequestID
|
||||
}
|
||||
|
||||
func InternalGetAcceptedFrontierFailed(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetAcceptedFrontierFailedOp,
|
||||
message: &GetAcceptedFrontierFailed{
|
||||
ChainID: chainID,
|
||||
RequestID: requestID,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type GetAcceptedFailed struct {
|
||||
ChainID ids.ID `json:"chain_id,omitempty"`
|
||||
RequestID uint32 `json:"request_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetAcceptedFailed) String() string {
|
||||
return fmt.Sprintf(
|
||||
"ChainID: %s RequestID: %d",
|
||||
m.ChainID, m.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
func (m *GetAcceptedFailed) GetChainId() []byte {
|
||||
return m.ChainID[:]
|
||||
}
|
||||
|
||||
func (m *GetAcceptedFailed) GetRequestId() uint32 {
|
||||
return m.RequestID
|
||||
}
|
||||
|
||||
func InternalGetAcceptedFailed(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetAcceptedFailedOp,
|
||||
message: &GetAcceptedFailed{
|
||||
ChainID: chainID,
|
||||
RequestID: requestID,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type GetAncestorsFailed struct {
|
||||
ChainID ids.ID `json:"chain_id,omitempty"`
|
||||
RequestID uint32 `json:"request_id,omitempty"`
|
||||
EngineType p2p.EngineType `json:"engine_type,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetAncestorsFailed) String() string {
|
||||
return fmt.Sprintf(
|
||||
"ChainID: %s RequestID: %d EngineType: %s",
|
||||
m.ChainID, m.RequestID, m.EngineType,
|
||||
)
|
||||
}
|
||||
|
||||
func (m *GetAncestorsFailed) GetChainId() []byte {
|
||||
return m.ChainID[:]
|
||||
}
|
||||
|
||||
func (m *GetAncestorsFailed) GetRequestId() uint32 {
|
||||
return m.RequestID
|
||||
}
|
||||
|
||||
func (m *GetAncestorsFailed) GetEngineType() p2p.EngineType {
|
||||
return m.EngineType
|
||||
}
|
||||
|
||||
func InternalGetAncestorsFailed(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
engineType p2p.EngineType,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetAncestorsFailedOp,
|
||||
message: &GetAncestorsFailed{
|
||||
ChainID: chainID,
|
||||
RequestID: requestID,
|
||||
EngineType: engineType,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type GetFailed struct {
|
||||
ChainID ids.ID `json:"chain_id,omitempty"`
|
||||
RequestID uint32 `json:"request_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetFailed) String() string {
|
||||
return fmt.Sprintf(
|
||||
"ChainID: %s RequestID: %d",
|
||||
m.ChainID, m.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
func (m *GetFailed) GetChainId() []byte {
|
||||
return m.ChainID[:]
|
||||
}
|
||||
|
||||
func (m *GetFailed) GetRequestId() uint32 {
|
||||
return m.RequestID
|
||||
}
|
||||
|
||||
func InternalGetFailed(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GetFailedOp,
|
||||
message: &GetFailed{
|
||||
ChainID: chainID,
|
||||
RequestID: requestID,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type QueryFailed struct {
|
||||
ChainID ids.ID `json:"chain_id,omitempty"`
|
||||
RequestID uint32 `json:"request_id,omitempty"`
|
||||
}
|
||||
|
||||
func (m *QueryFailed) String() string {
|
||||
return fmt.Sprintf(
|
||||
"ChainID: %s RequestID: %d",
|
||||
m.ChainID, m.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
func (m *QueryFailed) GetChainId() []byte {
|
||||
return m.ChainID[:]
|
||||
}
|
||||
|
||||
func (m *QueryFailed) GetRequestId() uint32 {
|
||||
return m.RequestID
|
||||
}
|
||||
|
||||
func InternalQueryFailed(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: QueryFailedOp,
|
||||
message: &QueryFailed{
|
||||
ChainID: chainID,
|
||||
RequestID: requestID,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type Connected struct {
|
||||
NodeVersion *version.Application `json:"node_version,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Connected) String() string {
|
||||
return fmt.Sprintf(
|
||||
"NodeVersion: %s",
|
||||
m.NodeVersion,
|
||||
)
|
||||
}
|
||||
|
||||
func InternalConnected(nodeID ids.NodeID, nodeVersion *version.Application) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: ConnectedOp,
|
||||
message: &Connected{
|
||||
NodeVersion: nodeVersion,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type Disconnected struct{}
|
||||
|
||||
func (Disconnected) String() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func InternalDisconnected(nodeID ids.NodeID) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: DisconnectedOp,
|
||||
message: disconnected,
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type VMMessage struct {
|
||||
Notification uint32 `json:"notification,omitempty"`
|
||||
}
|
||||
|
||||
func (m *VMMessage) String() string {
|
||||
return fmt.Sprintf(
|
||||
"Notification: %d",
|
||||
m.Notification,
|
||||
)
|
||||
}
|
||||
|
||||
func InternalVMMessage(
|
||||
nodeID ids.NodeID,
|
||||
notification uint32,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: NotifyOp,
|
||||
message: &VMMessage{
|
||||
Notification: notification,
|
||||
},
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
|
||||
type GossipRequest struct{}
|
||||
|
||||
func (GossipRequest) String() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func InternalGossipRequest(
|
||||
nodeID ids.NodeID,
|
||||
) InboundMessage {
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: GossipRequestOp,
|
||||
message: gossipRequest,
|
||||
expiration: mockable.MaxTime,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/luxfi/node/message (interfaces: OutboundMessage)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=messagemock -destination=messagemock/outbound_message.go -mock_names=OutboundMessage=OutboundMessage . OutboundMessage
|
||||
//
|
||||
|
||||
// Package messagemock is a generated GoMock package.
|
||||
package messagemock
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
message "github.com/luxfi/node/message"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// OutboundMessage is a mock of OutboundMessage interface.
|
||||
type OutboundMessage struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *OutboundMessageMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// OutboundMessageMockRecorder is the mock recorder for OutboundMessage.
|
||||
type OutboundMessageMockRecorder struct {
|
||||
mock *OutboundMessage
|
||||
}
|
||||
|
||||
// NewOutboundMessage creates a new mock instance.
|
||||
func NewOutboundMessage(ctrl *gomock.Controller) *OutboundMessage {
|
||||
mock := &OutboundMessage{ctrl: ctrl}
|
||||
mock.recorder = &OutboundMessageMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *OutboundMessage) EXPECT() *OutboundMessageMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// BypassThrottling mocks base method.
|
||||
func (m *OutboundMessage) BypassThrottling() bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BypassThrottling")
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// BypassThrottling indicates an expected call of BypassThrottling.
|
||||
func (mr *OutboundMessageMockRecorder) BypassThrottling() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BypassThrottling", reflect.TypeOf((*OutboundMessage)(nil).BypassThrottling))
|
||||
}
|
||||
|
||||
// Bytes mocks base method.
|
||||
func (m *OutboundMessage) Bytes() []byte {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Bytes")
|
||||
ret0, _ := ret[0].([]byte)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Bytes indicates an expected call of Bytes.
|
||||
func (mr *OutboundMessageMockRecorder) Bytes() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bytes", reflect.TypeOf((*OutboundMessage)(nil).Bytes))
|
||||
}
|
||||
|
||||
// BytesSavedCompression mocks base method.
|
||||
func (m *OutboundMessage) BytesSavedCompression() int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BytesSavedCompression")
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// BytesSavedCompression indicates an expected call of BytesSavedCompression.
|
||||
func (mr *OutboundMessageMockRecorder) BytesSavedCompression() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BytesSavedCompression", reflect.TypeOf((*OutboundMessage)(nil).BytesSavedCompression))
|
||||
}
|
||||
|
||||
// Op mocks base method.
|
||||
func (m *OutboundMessage) Op() message.Op {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Op")
|
||||
ret0, _ := ret[0].(message.Op)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Op indicates an expected call of Op.
|
||||
func (mr *OutboundMessageMockRecorder) Op() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Op", reflect.TypeOf((*OutboundMessage)(nil).Op))
|
||||
}
|
||||
@@ -0,0 +1,421 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/luxfi/node/message (interfaces: OutboundMsgBuilder)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=messagemock -destination=messagemock/outbound_message_builder.go -mock_names=OutboundMsgBuilder=OutboundMsgBuilder . OutboundMsgBuilder
|
||||
//
|
||||
|
||||
// Package messagemock is a generated GoMock package.
|
||||
package messagemock
|
||||
|
||||
import (
|
||||
netip "net/netip"
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
|
||||
ids "github.com/luxfi/ids"
|
||||
message "github.com/luxfi/node/message"
|
||||
p2p "github.com/luxfi/node/proto/p2p"
|
||||
"github.com/luxfi/net/endpoints"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// OutboundMsgBuilder is a mock of OutboundMsgBuilder interface.
|
||||
type OutboundMsgBuilder struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *OutboundMsgBuilderMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// OutboundMsgBuilderMockRecorder is the mock recorder for OutboundMsgBuilder.
|
||||
type OutboundMsgBuilderMockRecorder struct {
|
||||
mock *OutboundMsgBuilder
|
||||
}
|
||||
|
||||
// NewOutboundMsgBuilder creates a new mock instance.
|
||||
func NewOutboundMsgBuilder(ctrl *gomock.Controller) *OutboundMsgBuilder {
|
||||
mock := &OutboundMsgBuilder{ctrl: ctrl}
|
||||
mock.recorder = &OutboundMsgBuilderMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *OutboundMsgBuilder) EXPECT() *OutboundMsgBuilderMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Accepted mocks base method.
|
||||
func (m *OutboundMsgBuilder) Accepted(chainID ids.ID, requestID uint32, containerIDs []ids.ID) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Accepted", chainID, requestID, containerIDs)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Accepted indicates an expected call of Accepted.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Accepted(chainID, requestID, containerIDs any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accepted", reflect.TypeOf((*OutboundMsgBuilder)(nil).Accepted), chainID, requestID, containerIDs)
|
||||
}
|
||||
|
||||
// AcceptedFrontier mocks base method.
|
||||
func (m *OutboundMsgBuilder) AcceptedFrontier(chainID ids.ID, requestID uint32, containerID ids.ID) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AcceptedFrontier", chainID, requestID, containerID)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AcceptedFrontier indicates an expected call of AcceptedFrontier.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) AcceptedFrontier(chainID, requestID, containerID any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).AcceptedFrontier), chainID, requestID, containerID)
|
||||
}
|
||||
|
||||
// AcceptedStateSummary mocks base method.
|
||||
func (m *OutboundMsgBuilder) AcceptedStateSummary(chainID ids.ID, requestID uint32, summaryIDs []ids.ID) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AcceptedStateSummary", chainID, requestID, summaryIDs)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AcceptedStateSummary indicates an expected call of AcceptedStateSummary.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) AcceptedStateSummary(chainID, requestID, summaryIDs any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedStateSummary", reflect.TypeOf((*OutboundMsgBuilder)(nil).AcceptedStateSummary), chainID, requestID, summaryIDs)
|
||||
}
|
||||
|
||||
// Ancestors mocks base method.
|
||||
func (m *OutboundMsgBuilder) Ancestors(chainID ids.ID, requestID uint32, containers [][]byte) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Ancestors", chainID, requestID, containers)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Ancestors indicates an expected call of Ancestors.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Ancestors(chainID, requestID, containers any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ancestors", reflect.TypeOf((*OutboundMsgBuilder)(nil).Ancestors), chainID, requestID, containers)
|
||||
}
|
||||
|
||||
// Error mocks base method.
|
||||
func (m *OutboundMsgBuilder) Error(chainID ids.ID, requestID uint32, errorCode int32, errorMessage string) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Error", chainID, requestID, errorCode, errorMessage)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Error indicates an expected call of Error.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Error(chainID, requestID, errorCode, errorMessage any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*OutboundMsgBuilder)(nil).Error), chainID, requestID, errorCode, errorMessage)
|
||||
}
|
||||
|
||||
// Gossip mocks base method.
|
||||
func (m *OutboundMsgBuilder) Gossip(chainID ids.ID, msg []byte) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Gossip", chainID, msg)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Gossip indicates an expected call of Gossip.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Gossip(chainID, msg any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Gossip", reflect.TypeOf((*OutboundMsgBuilder)(nil).Gossip), chainID, msg)
|
||||
}
|
||||
|
||||
// Request mocks base method.
|
||||
func (m *OutboundMsgBuilder) Request(chainID ids.ID, requestID uint32, deadline time.Duration, msg []byte) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Request", chainID, requestID, deadline, msg)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Request indicates an expected call of Request.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Request(chainID, requestID, deadline, msg any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Request", reflect.TypeOf((*OutboundMsgBuilder)(nil).Request), chainID, requestID, deadline, msg)
|
||||
}
|
||||
|
||||
// Response mocks base method.
|
||||
func (m *OutboundMsgBuilder) Response(chainID ids.ID, requestID uint32, msg []byte) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Response", chainID, requestID, msg)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Response indicates an expected call of Response.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Response(chainID, requestID, msg any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Response", reflect.TypeOf((*OutboundMsgBuilder)(nil).Response), chainID, requestID, msg)
|
||||
}
|
||||
|
||||
// Chits mocks base method.
|
||||
func (m *OutboundMsgBuilder) Chits(chainID ids.ID, requestID uint32, preferredID, preferredIDAtHeight, acceptedID ids.ID, acceptedHeight uint64) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Chits", chainID, requestID, preferredID, preferredIDAtHeight, acceptedID, acceptedHeight)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Chits indicates an expected call of Chits.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Chits(chainID, requestID, preferredID, preferredIDAtHeight, acceptedID, acceptedHeight any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chits", reflect.TypeOf((*OutboundMsgBuilder)(nil).Chits), chainID, requestID, preferredID, preferredIDAtHeight, acceptedID, acceptedHeight)
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *OutboundMsgBuilder) Get(chainID ids.ID, requestID uint32, deadline time.Duration, containerID ids.ID) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", chainID, requestID, deadline, containerID)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Get(chainID, requestID, deadline, containerID any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*OutboundMsgBuilder)(nil).Get), chainID, requestID, deadline, containerID)
|
||||
}
|
||||
|
||||
// GetAccepted mocks base method.
|
||||
func (m *OutboundMsgBuilder) GetAccepted(chainID ids.ID, requestID uint32, deadline time.Duration, containerIDs []ids.ID) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAccepted", chainID, requestID, deadline, containerIDs)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAccepted indicates an expected call of GetAccepted.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) GetAccepted(chainID, requestID, deadline, containerIDs any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccepted", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAccepted), chainID, requestID, deadline, containerIDs)
|
||||
}
|
||||
|
||||
// GetAcceptedFrontier mocks base method.
|
||||
func (m *OutboundMsgBuilder) GetAcceptedFrontier(chainID ids.ID, requestID uint32, deadline time.Duration) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAcceptedFrontier", chainID, requestID, deadline)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAcceptedFrontier indicates an expected call of GetAcceptedFrontier.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) GetAcceptedFrontier(chainID, requestID, deadline any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAcceptedFrontier), chainID, requestID, deadline)
|
||||
}
|
||||
|
||||
// GetAcceptedStateSummary mocks base method.
|
||||
func (m *OutboundMsgBuilder) GetAcceptedStateSummary(chainID ids.ID, requestID uint32, deadline time.Duration, heights []uint64) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAcceptedStateSummary", chainID, requestID, deadline, heights)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAcceptedStateSummary indicates an expected call of GetAcceptedStateSummary.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) GetAcceptedStateSummary(chainID, requestID, deadline, heights any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedStateSummary", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAcceptedStateSummary), chainID, requestID, deadline, heights)
|
||||
}
|
||||
|
||||
// GetAncestors mocks base method.
|
||||
func (m *OutboundMsgBuilder) GetAncestors(chainID ids.ID, requestID uint32, deadline time.Duration, containerID ids.ID, engineType p2p.EngineType) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAncestors", chainID, requestID, deadline, containerID, engineType)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAncestors indicates an expected call of GetAncestors.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) GetAncestors(chainID, requestID, deadline, containerID, engineType any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAncestors", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAncestors), chainID, requestID, deadline, containerID, engineType)
|
||||
}
|
||||
|
||||
// GetPeerList mocks base method.
|
||||
func (m *OutboundMsgBuilder) GetPeerList(knownPeersFilter, knownPeersSalt []byte, requestAllNetIPs bool) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPeerList", knownPeersFilter, knownPeersSalt, requestAllNetIPs)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetPeerList indicates an expected call of GetPeerList.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) GetPeerList(knownPeersFilter, knownPeersSalt, requestAllNetIPs any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPeerList", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetPeerList), knownPeersFilter, knownPeersSalt, requestAllNetIPs)
|
||||
}
|
||||
|
||||
// GetStateSummaryFrontier mocks base method.
|
||||
func (m *OutboundMsgBuilder) GetStateSummaryFrontier(chainID ids.ID, requestID uint32, deadline time.Duration) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetStateSummaryFrontier", chainID, requestID, deadline)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetStateSummaryFrontier indicates an expected call of GetStateSummaryFrontier.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) GetStateSummaryFrontier(chainID, requestID, deadline any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetStateSummaryFrontier), chainID, requestID, deadline)
|
||||
}
|
||||
|
||||
// Handshake mocks base method.
|
||||
func (m *OutboundMsgBuilder) Handshake(networkID uint32, myTime uint64, ip netip.AddrPort, client string, major, minor, patch uint32, ipSigningTime uint64, ipNodeIDSig, ipBLSSig []byte, trackedNets []ids.ID, supportedLPs, objectedLPs []uint32, knownPeersFilter, knownPeersSalt []byte, requestAllNetIPs bool) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Handshake", networkID, myTime, ip, client, major, minor, patch, ipSigningTime, ipNodeIDSig, ipBLSSig, trackedNets, supportedLPs, objectedLPs, knownPeersFilter, knownPeersSalt, requestAllNetIPs)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Handshake indicates an expected call of Handshake.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Handshake(networkID, myTime, ip, client, major, minor, patch, ipSigningTime, ipNodeIDSig, ipBLSSig, trackedNets, supportedLPs, objectedLPs, knownPeersFilter, knownPeersSalt, requestAllNetIPs any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*OutboundMsgBuilder)(nil).Handshake), networkID, myTime, ip, client, major, minor, patch, ipSigningTime, ipNodeIDSig, ipBLSSig, trackedNets, supportedLPs, objectedLPs, knownPeersFilter, knownPeersSalt, requestAllNetIPs)
|
||||
}
|
||||
|
||||
// PeerList mocks base method.
|
||||
func (m *OutboundMsgBuilder) PeerList(peers []*endpoints.ClaimedIPPort, bypassThrottling bool) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PeerList", peers, bypassThrottling)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PeerList indicates an expected call of PeerList.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) PeerList(peers, bypassThrottling any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerList", reflect.TypeOf((*OutboundMsgBuilder)(nil).PeerList), peers, bypassThrottling)
|
||||
}
|
||||
|
||||
// Ping mocks base method.
|
||||
func (m *OutboundMsgBuilder) Ping(primaryUptime uint32) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Ping", primaryUptime)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Ping indicates an expected call of Ping.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Ping(primaryUptime any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*OutboundMsgBuilder)(nil).Ping), primaryUptime)
|
||||
}
|
||||
|
||||
// Pong mocks base method.
|
||||
func (m *OutboundMsgBuilder) Pong() (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Pong")
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Pong indicates an expected call of Pong.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Pong() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pong", reflect.TypeOf((*OutboundMsgBuilder)(nil).Pong))
|
||||
}
|
||||
|
||||
// PullQuery mocks base method.
|
||||
func (m *OutboundMsgBuilder) PullQuery(chainID ids.ID, requestID uint32, deadline time.Duration, containerID ids.ID, requestedHeight uint64) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PullQuery", chainID, requestID, deadline, containerID, requestedHeight)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PullQuery indicates an expected call of PullQuery.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) PullQuery(chainID, requestID, deadline, containerID, requestedHeight any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PullQuery", reflect.TypeOf((*OutboundMsgBuilder)(nil).PullQuery), chainID, requestID, deadline, containerID, requestedHeight)
|
||||
}
|
||||
|
||||
// PushQuery mocks base method.
|
||||
func (m *OutboundMsgBuilder) PushQuery(chainID ids.ID, requestID uint32, deadline time.Duration, container []byte, requestedHeight uint64) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PushQuery", chainID, requestID, deadline, container, requestedHeight)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PushQuery indicates an expected call of PushQuery.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) PushQuery(chainID, requestID, deadline, container, requestedHeight any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushQuery", reflect.TypeOf((*OutboundMsgBuilder)(nil).PushQuery), chainID, requestID, deadline, container, requestedHeight)
|
||||
}
|
||||
|
||||
// Put mocks base method.
|
||||
func (m *OutboundMsgBuilder) Put(chainID ids.ID, requestID uint32, container []byte) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Put", chainID, requestID, container)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Put indicates an expected call of Put.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) Put(chainID, requestID, container any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*OutboundMsgBuilder)(nil).Put), chainID, requestID, container)
|
||||
}
|
||||
|
||||
// BFTMessage mocks base method.
|
||||
func (m *OutboundMsgBuilder) BFTMessage(msg *p2p.BFT) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BFTMessage", msg)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BFTMessage indicates an expected call of BFTMessage.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) BFTMessage(msg any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BFTMessage", reflect.TypeOf((*OutboundMsgBuilder)(nil).BFTMessage), msg)
|
||||
}
|
||||
|
||||
// StateSummaryFrontier mocks base method.
|
||||
func (m *OutboundMsgBuilder) StateSummaryFrontier(chainID ids.ID, requestID uint32, summary []byte) (message.OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "StateSummaryFrontier", chainID, requestID, summary)
|
||||
ret0, _ := ret[0].(message.OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// StateSummaryFrontier indicates an expected call of StateSummaryFrontier.
|
||||
func (mr *OutboundMsgBuilderMockRecorder) StateSummaryFrontier(chainID, requestID, summary any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).StateSummaryFrontier), chainID, requestID, summary)
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/constants"
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/metric"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
"github.com/luxfi/timer/mockable"
|
||||
compression "github.com/luxfi/compress"
|
||||
)
|
||||
|
||||
const (
|
||||
typeLabel = "type"
|
||||
opLabel = "op"
|
||||
directionLabel = "direction"
|
||||
|
||||
compressionLabel = "compression"
|
||||
decompressionLabel = "decompression"
|
||||
)
|
||||
|
||||
var (
|
||||
_ InboundMessage = (*inboundMessage)(nil)
|
||||
_ OutboundMessage = (*outboundMessage)(nil)
|
||||
|
||||
metricLabels = []string{typeLabel, opLabel, directionLabel}
|
||||
|
||||
errUnknownCompressionType = errors.New("message is compressed with an unknown compression type")
|
||||
)
|
||||
|
||||
// InboundMessage represents a set of fields for an inbound message
|
||||
type InboundMessage interface {
|
||||
fmt.Stringer
|
||||
// NodeID returns the ID of the node that sent this message
|
||||
NodeID() ids.NodeID
|
||||
// Op returns the op that describes this message type
|
||||
Op() Op
|
||||
// Message returns the message that was sent
|
||||
Message() fmt.Stringer
|
||||
// Expiration returns the time that the sender will have already timed out
|
||||
// this request
|
||||
Expiration() time.Time
|
||||
// OnFinishedHandling must be called one time when this message has been
|
||||
// handled by the message handler
|
||||
OnFinishedHandling()
|
||||
// BytesSavedCompression returns the number of bytes that this message saved
|
||||
// due to being compressed
|
||||
BytesSavedCompression() int
|
||||
}
|
||||
|
||||
type inboundMessage struct {
|
||||
nodeID ids.NodeID
|
||||
op Op
|
||||
message fmt.Stringer
|
||||
expiration time.Time
|
||||
onFinishedHandling func()
|
||||
bytesSavedCompression int
|
||||
}
|
||||
|
||||
func (m *inboundMessage) NodeID() ids.NodeID {
|
||||
return m.nodeID
|
||||
}
|
||||
|
||||
func (m *inboundMessage) Op() Op {
|
||||
return m.op
|
||||
}
|
||||
|
||||
func (m *inboundMessage) Message() fmt.Stringer {
|
||||
return m.message
|
||||
}
|
||||
|
||||
func (m *inboundMessage) Expiration() time.Time {
|
||||
return m.expiration
|
||||
}
|
||||
|
||||
func (m *inboundMessage) OnFinishedHandling() {
|
||||
if m.onFinishedHandling != nil {
|
||||
m.onFinishedHandling()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *inboundMessage) BytesSavedCompression() int {
|
||||
return m.bytesSavedCompression
|
||||
}
|
||||
|
||||
func (m *inboundMessage) String() string {
|
||||
return fmt.Sprintf("%s Op: %s Message: %s",
|
||||
m.nodeID, m.op, m.message)
|
||||
}
|
||||
|
||||
// OutboundMessage represents a set of fields for an outbound message that can
|
||||
// be serialized into a byte stream
|
||||
type OutboundMessage interface {
|
||||
// BypassThrottling returns true if we should send this message, regardless
|
||||
// of any outbound message throttling
|
||||
BypassThrottling() bool
|
||||
// Op returns the op that describes this message type
|
||||
Op() Op
|
||||
// Bytes returns the bytes that will be sent
|
||||
Bytes() []byte
|
||||
// BytesSavedCompression returns the number of bytes that this message saved
|
||||
// due to being compressed
|
||||
BytesSavedCompression() int
|
||||
}
|
||||
|
||||
type outboundMessage struct {
|
||||
bypassThrottling bool
|
||||
op Op
|
||||
bytes []byte
|
||||
bytesSavedCompression int
|
||||
}
|
||||
|
||||
func (m *outboundMessage) BypassThrottling() bool {
|
||||
return m.bypassThrottling
|
||||
}
|
||||
|
||||
func (m *outboundMessage) Op() Op {
|
||||
return m.op
|
||||
}
|
||||
|
||||
func (m *outboundMessage) Bytes() []byte {
|
||||
return m.bytes
|
||||
}
|
||||
|
||||
func (m *outboundMessage) BytesSavedCompression() int {
|
||||
return m.bytesSavedCompression
|
||||
}
|
||||
|
||||
type msgBuilder struct {
|
||||
zstdCompressor compression.Compressor
|
||||
count metric.CounterVec // type + op + direction
|
||||
duration metric.GaugeVec // type + op + direction
|
||||
|
||||
maxMessageTimeout time.Duration
|
||||
}
|
||||
|
||||
func newMsgBuilder(
|
||||
metrics metric.Registerer,
|
||||
maxMessageTimeout time.Duration,
|
||||
) (*msgBuilder, error) {
|
||||
zstdCompressor, err := compression.NewZstdCompressor(constants.DefaultMaxMessageSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mb := &msgBuilder{
|
||||
zstdCompressor: zstdCompressor,
|
||||
count: metric.NewCounterVec(
|
||||
metric.CounterOpts{
|
||||
Name: "codec_compressed_count",
|
||||
Help: "number of compressed messages",
|
||||
},
|
||||
metricLabels,
|
||||
),
|
||||
duration: metric.NewGaugeVec(
|
||||
metric.GaugeOpts{
|
||||
Name: "codec_compressed_duration",
|
||||
Help: "time spent handling compressed messages",
|
||||
},
|
||||
metricLabels,
|
||||
),
|
||||
|
||||
maxMessageTimeout: maxMessageTimeout,
|
||||
}
|
||||
return mb, nil
|
||||
}
|
||||
|
||||
func (mb *msgBuilder) marshal(
|
||||
uncompressedMsg *p2p.Message,
|
||||
compressionType compression.Type,
|
||||
) ([]byte, int, Op, error) {
|
||||
uncompressedMsgBytes, err := p2p.Marshal(uncompressedMsg)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
op, err := ToOp(uncompressedMsg)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
// If compression is enabled, we marshal twice:
|
||||
// 1. the original message
|
||||
// 2. the message with compressed bytes
|
||||
//
|
||||
// This recursive packing allows us to avoid an extra compression on/off
|
||||
// field in the message.
|
||||
var (
|
||||
startTime = time.Now()
|
||||
compressedMsg p2p.Message
|
||||
)
|
||||
switch compressionType {
|
||||
case compression.TypeNone:
|
||||
return uncompressedMsgBytes, 0, op, nil
|
||||
case compression.TypeZstd:
|
||||
compressedBytes, err := mb.zstdCompressor.Compress(uncompressedMsgBytes)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
compressedMsg = p2p.Message{
|
||||
Message: &p2p.Message_CompressedZstd{
|
||||
CompressedZstd: compressedBytes,
|
||||
},
|
||||
}
|
||||
default:
|
||||
return nil, 0, 0, errUnknownCompressionType
|
||||
}
|
||||
|
||||
compressedMsgBytes, err := p2p.Marshal(&compressedMsg)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
compressTook := time.Since(startTime)
|
||||
|
||||
labels := metric.Labels{
|
||||
typeLabel: compressionType.String(),
|
||||
opLabel: op.String(),
|
||||
directionLabel: compressionLabel,
|
||||
}
|
||||
mb.count.With(labels).Inc()
|
||||
mb.duration.With(labels).Add(float64(compressTook))
|
||||
|
||||
bytesSaved := len(uncompressedMsgBytes) - len(compressedMsgBytes)
|
||||
return compressedMsgBytes, bytesSaved, op, nil
|
||||
}
|
||||
|
||||
func (mb *msgBuilder) unmarshal(b []byte) (*p2p.Message, int, Op, error) {
|
||||
m := new(p2p.Message)
|
||||
if err := p2p.Unmarshal(b, m); err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
// Figure out what compression type, if any, was used to compress the message.
|
||||
var (
|
||||
compressor compression.Compressor
|
||||
compressedBytes []byte
|
||||
zstdCompressed = m.GetCompressedZstd()
|
||||
)
|
||||
switch {
|
||||
case len(zstdCompressed) > 0:
|
||||
compressor = mb.zstdCompressor
|
||||
compressedBytes = zstdCompressed
|
||||
default:
|
||||
// The message wasn't compressed
|
||||
op, err := ToOp(m)
|
||||
return m, 0, op, err
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
decompressed, err := compressor.Decompress(compressedBytes)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
bytesSavedCompression := len(decompressed) - len(compressedBytes)
|
||||
|
||||
if err := p2p.Unmarshal(decompressed, m); err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
decompressTook := time.Since(startTime)
|
||||
|
||||
// Record decompression time metrics
|
||||
op, err := ToOp(m)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
labels := metric.Labels{
|
||||
typeLabel: compression.TypeZstd.String(),
|
||||
opLabel: op.String(),
|
||||
directionLabel: decompressionLabel,
|
||||
}
|
||||
mb.count.With(labels).Inc()
|
||||
mb.duration.With(labels).Add(float64(decompressTook))
|
||||
|
||||
return m, bytesSavedCompression, op, nil
|
||||
}
|
||||
|
||||
func (mb *msgBuilder) createOutbound(m *p2p.Message, compressionType compression.Type, bypassThrottling bool) (*outboundMessage, error) {
|
||||
b, saved, op, err := mb.marshal(m, compressionType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &outboundMessage{
|
||||
bypassThrottling: bypassThrottling,
|
||||
op: op,
|
||||
bytes: b,
|
||||
bytesSavedCompression: saved,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (mb *msgBuilder) parseInbound(
|
||||
bytes []byte,
|
||||
nodeID ids.NodeID,
|
||||
onFinishedHandling func(),
|
||||
) (*inboundMessage, error) {
|
||||
m, bytesSavedCompression, op, err := mb.unmarshal(bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msg, err := Unwrap(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expiration := mockable.MaxTime
|
||||
if deadline, ok := GetDeadline(msg); ok {
|
||||
deadline = min(deadline, mb.maxMessageTimeout)
|
||||
expiration = time.Now().Add(deadline)
|
||||
}
|
||||
|
||||
return &inboundMessage{
|
||||
nodeID: nodeID,
|
||||
op: op,
|
||||
message: msg,
|
||||
expiration: expiration,
|
||||
onFinishedHandling: onFinishedHandling,
|
||||
bytesSavedCompression: bytesSavedCompression,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"github.com/luxfi/metric"
|
||||
"net"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
compression "github.com/luxfi/compress"
|
||||
)
|
||||
|
||||
var (
|
||||
dummyNodeID = ids.EmptyNodeID
|
||||
dummyOnFinishedHandling = func() {}
|
||||
)
|
||||
|
||||
// Benchmarks marshal-ing "Handshake" message.
|
||||
//
|
||||
// e.g.,
|
||||
//
|
||||
// $ go install -v golang.org/x/tools/cmd/benchcmp@latest
|
||||
// $ go install -v golang.org/x/perf/cmd/benchstat@latest
|
||||
//
|
||||
// $ go test -run=NONE -bench=BenchmarkMarshalHandshake > /tmp/cpu.before.txt
|
||||
// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalHandshake > /tmp/cpu.after.txt
|
||||
// $ benchcmp /tmp/cpu.before.txt /tmp/cpu.after.txt
|
||||
// $ benchstat -alpha 0.03 -geomean /tmp/cpu.before.txt /tmp/cpu.after.txt
|
||||
//
|
||||
// $ go test -run=NONE -bench=BenchmarkMarshalHandshake -benchmem > /tmp/mem.before.txt
|
||||
// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalHandshake -benchmem > /tmp/mem.after.txt
|
||||
// $ benchcmp /tmp/mem.before.txt /tmp/mem.after.txt
|
||||
// $ benchstat -alpha 0.03 -geomean /tmp/mem.before.txt /tmp/mem.after.txt
|
||||
func BenchmarkMarshalHandshake(b *testing.B) {
|
||||
require := require.New(b)
|
||||
|
||||
id := ids.GenerateTestID()
|
||||
msg := p2p.Message{
|
||||
Message: &p2p.Message_Handshake{
|
||||
Handshake: &p2p.Handshake{
|
||||
NetworkId: uint32(1337),
|
||||
MyTime: uint64(time.Now().Unix()),
|
||||
IpAddr: []byte(net.IPv4(1, 2, 3, 4).To16()),
|
||||
IpPort: 0,
|
||||
IpSigningTime: uint64(time.Now().Unix()),
|
||||
IpNodeIdSig: []byte{'y', 'e', 'e', 't'},
|
||||
TrackedNets: [][]byte{id[:]},
|
||||
IpBlsSig: []byte{'y', 'e', 'e', 't', '2'},
|
||||
},
|
||||
},
|
||||
}
|
||||
msgLen := p2p.Size(&msg)
|
||||
|
||||
useBuilder := os.Getenv("USE_BUILDER") != ""
|
||||
|
||||
codec, err := newMsgBuilder(metric.NewRegistry(), 10*time.Second)
|
||||
require.NoError(err)
|
||||
|
||||
b.Logf("proto length %d-byte (use builder %v)", msgLen, useBuilder)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if useBuilder {
|
||||
_, err = codec.createOutbound(&msg, compression.TypeNone, false)
|
||||
} else {
|
||||
_, err = p2p.Marshal(&msg)
|
||||
}
|
||||
require.NoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmarks unmarshal-ing "Version" message.
|
||||
//
|
||||
// e.g.,
|
||||
//
|
||||
// $ go install -v golang.org/x/tools/cmd/benchcmp@latest
|
||||
// $ go install -v golang.org/x/perf/cmd/benchstat@latest
|
||||
//
|
||||
// $ go test -run=NONE -bench=BenchmarkUnmarshalHandshake > /tmp/cpu.before.txt
|
||||
// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkUnmarshalHandshake > /tmp/cpu.after.txt
|
||||
// $ benchcmp /tmp/cpu.before.txt /tmp/cpu.after.txt
|
||||
// $ benchstat -alpha 0.03 -geomean /tmp/cpu.before.txt /tmp/cpu.after.txt
|
||||
//
|
||||
// $ go test -run=NONE -bench=BenchmarkUnmarshalHandshake -benchmem > /tmp/mem.before.txt
|
||||
// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkUnmarshalHandshake -benchmem > /tmp/mem.after.txt
|
||||
// $ benchcmp /tmp/mem.before.txt /tmp/mem.after.txt
|
||||
// $ benchstat -alpha 0.03 -geomean /tmp/mem.before.txt /tmp/mem.after.txt
|
||||
func BenchmarkUnmarshalHandshake(b *testing.B) {
|
||||
require := require.New(b)
|
||||
|
||||
b.StopTimer()
|
||||
|
||||
id := ids.GenerateTestID()
|
||||
msg := p2p.Message{
|
||||
Message: &p2p.Message_Handshake{
|
||||
Handshake: &p2p.Handshake{
|
||||
NetworkId: uint32(1337),
|
||||
MyTime: uint64(time.Now().Unix()),
|
||||
IpAddr: []byte(net.IPv4(1, 2, 3, 4).To16()),
|
||||
IpPort: 0,
|
||||
IpSigningTime: uint64(time.Now().Unix()),
|
||||
IpNodeIdSig: []byte{'y', 'e', 'e', 't'},
|
||||
TrackedNets: [][]byte{id[:]},
|
||||
IpBlsSig: []byte{'y', 'e', 'e', 't', '2'},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rawMsg, err := p2p.Marshal(&msg)
|
||||
require.NoError(err)
|
||||
|
||||
useBuilder := os.Getenv("USE_BUILDER") != ""
|
||||
codec, err := newMsgBuilder(metric.NewRegistry(), 10*time.Second)
|
||||
require.NoError(err)
|
||||
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if useBuilder {
|
||||
_, err = codec.parseInbound(rawMsg, dummyNodeID, dummyOnFinishedHandling)
|
||||
require.NoError(err)
|
||||
} else {
|
||||
var msg p2p.Message
|
||||
require.NoError(p2p.Unmarshal(rawMsg, &msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,755 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/luxfi/metric"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
"github.com/luxfi/node/staking"
|
||||
compression "github.com/luxfi/compress"
|
||||
)
|
||||
|
||||
func TestMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mb, err := newMsgBuilder(
|
||||
metric.NewRegistry(),
|
||||
5*time.Second,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
testID := ids.GenerateTestID()
|
||||
compressibleContainers := [][]byte{
|
||||
bytes.Repeat([]byte{0}, 100),
|
||||
bytes.Repeat([]byte{0}, 32),
|
||||
bytes.Repeat([]byte{0}, 32),
|
||||
}
|
||||
|
||||
testCertRaw, testKeyRaw, err := staking.NewCertAndKeyBytes()
|
||||
require.NoError(t, err)
|
||||
|
||||
testTLSCert, err := staking.LoadTLSCertFromBytes(testKeyRaw, testCertRaw)
|
||||
require.NoError(t, err)
|
||||
|
||||
nowUnix := time.Now().Unix()
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
op Op
|
||||
msg *p2p.Message
|
||||
compressionType compression.Type
|
||||
bypassThrottling bool
|
||||
bytesSaved bool // if true, outbound message saved bytes must be non-zero
|
||||
}{
|
||||
{
|
||||
desc: "ping message with no compression no uptime",
|
||||
op: PingOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Ping{
|
||||
Ping: &p2p.Ping{},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "pong message with no compression",
|
||||
op: PongOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Pong{
|
||||
Pong: &p2p.Pong{},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "ping message with no compression and uptime",
|
||||
op: PingOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Ping{
|
||||
Ping: &p2p.Ping{
|
||||
Uptime: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "Handshake message with no compression",
|
||||
op: HandshakeOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Handshake{
|
||||
Handshake: &p2p.Handshake{
|
||||
NetworkId: uint32(1337),
|
||||
MyTime: uint64(nowUnix),
|
||||
IpAddr: []byte(net.IPv6zero),
|
||||
IpPort: 9631,
|
||||
IpSigningTime: uint64(nowUnix),
|
||||
IpNodeIdSig: []byte{'y', 'e', 'e', 't'},
|
||||
TrackedNets: [][]byte{testID[:]},
|
||||
IpBlsSig: []byte{'y', 'e', 'e', 't', '2'},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "get_peer_list message with no compression",
|
||||
op: GetPeerListOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_GetPeerList{
|
||||
GetPeerList: &p2p.GetPeerList{
|
||||
KnownPeers: &p2p.BloomFilter{
|
||||
Filter: make([]byte, 2048),
|
||||
Salt: make([]byte, 32),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: false,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "get_peer_list message with zstd compression",
|
||||
op: GetPeerListOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_GetPeerList{
|
||||
GetPeerList: &p2p.GetPeerList{
|
||||
KnownPeers: &p2p.BloomFilter{
|
||||
Filter: make([]byte, 2048),
|
||||
Salt: make([]byte, 32),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: false,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "peer_list message with no compression",
|
||||
op: PeerListOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_PeerList_{
|
||||
PeerList_: &p2p.PeerList{
|
||||
ClaimedIpPorts: []*p2p.ClaimedIpPort{
|
||||
{
|
||||
X509Certificate: testTLSCert.Certificate[0],
|
||||
IpAddr: []byte(net.IPv4zero),
|
||||
IpPort: 10,
|
||||
Timestamp: 1,
|
||||
Signature: []byte{0},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "peer_list message with zstd compression",
|
||||
op: PeerListOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_PeerList_{
|
||||
PeerList_: &p2p.PeerList{
|
||||
ClaimedIpPorts: []*p2p.ClaimedIpPort{
|
||||
{
|
||||
X509Certificate: testTLSCert.Certificate[0],
|
||||
IpAddr: []byte(net.IPv6zero),
|
||||
IpPort: 9631,
|
||||
Timestamp: uint64(nowUnix),
|
||||
Signature: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "get_state_summary_frontier message with no compression",
|
||||
op: GetStateSummaryFrontierOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_GetStateSummaryFrontier{
|
||||
GetStateSummaryFrontier: &p2p.GetStateSummaryFrontier{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "state_summary_frontier message with no compression",
|
||||
op: StateSummaryFrontierOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_StateSummaryFrontier_{
|
||||
StateSummaryFrontier_: &p2p.StateSummaryFrontier{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Summary: []byte{0},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "state_summary_frontier message with zstd compression",
|
||||
op: StateSummaryFrontierOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_StateSummaryFrontier_{
|
||||
StateSummaryFrontier_: &p2p.StateSummaryFrontier{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Summary: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "get_accepted_state_summary message with no compression",
|
||||
op: GetAcceptedStateSummaryOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_GetAcceptedStateSummary{
|
||||
GetAcceptedStateSummary: &p2p.GetAcceptedStateSummary{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
Heights: []uint64{0},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "get_accepted_state_summary message with zstd compression",
|
||||
op: GetAcceptedStateSummaryOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_GetAcceptedStateSummary{
|
||||
GetAcceptedStateSummary: &p2p.GetAcceptedStateSummary{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
Heights: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false, // Small data may not benefit from compression
|
||||
},
|
||||
{
|
||||
desc: "accepted_state_summary message with no compression",
|
||||
op: AcceptedStateSummaryOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_AcceptedStateSummary_{
|
||||
AcceptedStateSummary_: &p2p.AcceptedStateSummary{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
SummaryIds: [][]byte{testID[:], testID[:]},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "accepted_state_summary message with zstd compression",
|
||||
op: AcceptedStateSummaryOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_AcceptedStateSummary_{
|
||||
AcceptedStateSummary_: &p2p.AcceptedStateSummary{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
SummaryIds: [][]byte{testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:]},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "get_accepted_frontier message with no compression",
|
||||
op: GetAcceptedFrontierOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_GetAcceptedFrontier{
|
||||
GetAcceptedFrontier: &p2p.GetAcceptedFrontier{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "accepted_frontier message with no compression",
|
||||
op: AcceptedFrontierOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_AcceptedFrontier_{
|
||||
AcceptedFrontier_: &p2p.AcceptedFrontier{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
ContainerId: testID[:],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "get_accepted message with no compression",
|
||||
op: GetAcceptedOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_GetAccepted{
|
||||
GetAccepted: &p2p.GetAccepted{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
ContainerIds: [][]byte{testID[:], testID[:]},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "accepted message with no compression",
|
||||
op: AcceptedOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Accepted_{
|
||||
Accepted_: &p2p.Accepted{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
ContainerIds: [][]byte{testID[:], testID[:]},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "get_ancestors message with no compression",
|
||||
op: GetAncestorsOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_GetAncestors{
|
||||
GetAncestors: &p2p.GetAncestors{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
ContainerId: testID[:],
|
||||
EngineType: p2p.EngineType_ENGINE_TYPE_DAG,
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "ancestors message with no compression",
|
||||
op: AncestorsOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Ancestors_{
|
||||
Ancestors_: &p2p.Ancestors{
|
||||
ChainId: testID[:],
|
||||
RequestId: 12345,
|
||||
Containers: compressibleContainers,
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "ancestors message with zstd compression",
|
||||
op: AncestorsOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Ancestors_{
|
||||
Ancestors_: &p2p.Ancestors{
|
||||
ChainId: testID[:],
|
||||
RequestId: 12345,
|
||||
Containers: compressibleContainers,
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "get message with no compression",
|
||||
op: GetOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Get{
|
||||
Get: &p2p.Get{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
ContainerId: testID[:],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "put message with no compression",
|
||||
op: PutOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Put{
|
||||
Put: &p2p.Put{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Container: []byte{0},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "put message with zstd compression",
|
||||
op: PutOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Put{
|
||||
Put: &p2p.Put{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Container: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "push_query message with no compression",
|
||||
op: PushQueryOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_PushQuery{
|
||||
PushQuery: &p2p.PushQuery{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
Container: []byte{0},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "push_query message with zstd compression",
|
||||
op: PushQueryOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_PushQuery{
|
||||
PushQuery: &p2p.PushQuery{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
Container: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "pull_query message with no compression",
|
||||
op: PullQueryOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_PullQuery{
|
||||
PullQuery: &p2p.PullQuery{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
ContainerId: testID[:],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "qbit message with no compression",
|
||||
op: QbitOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Chits{
|
||||
Chits: &p2p.Chits{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
PreferredId: testID[:],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "app_request message with no compression",
|
||||
op: RequestOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Request{
|
||||
Request: &p2p.Request{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
AppBytes: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "app_request message with zstd compression",
|
||||
op: RequestOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Request{
|
||||
Request: &p2p.Request{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
Deadline: 1,
|
||||
AppBytes: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "app_response message with no compression",
|
||||
op: ResponseOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Response{
|
||||
Response: &p2p.Response{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
AppBytes: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "app_response message with zstd compression",
|
||||
op: ResponseOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Response{
|
||||
Response: &p2p.Response{
|
||||
ChainId: testID[:],
|
||||
RequestId: 1,
|
||||
AppBytes: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "app_gossip message with no compression",
|
||||
op: GossipOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Gossip{
|
||||
Gossip: &p2p.Gossip{
|
||||
ChainId: testID[:],
|
||||
AppBytes: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
{
|
||||
desc: "app_gossip message with zstd compression",
|
||||
op: GossipOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_Gossip{
|
||||
Gossip: &p2p.Gossip{
|
||||
ChainId: testID[:],
|
||||
AppBytes: compressibleContainers[0],
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeZstd,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: true,
|
||||
},
|
||||
{
|
||||
desc: "bft message with no compression",
|
||||
op: BFTOp,
|
||||
msg: &p2p.Message{
|
||||
Message: &p2p.Message_BFT{
|
||||
BFT: &p2p.BFT{
|
||||
ChainId: testID[:],
|
||||
Message: &p2p.BFT_ReplicationRequest{
|
||||
ReplicationRequest: &p2p.ReplicationRequest{
|
||||
Seqs: []uint64{1, 2, 3},
|
||||
LatestRound: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
compressionType: compression.TypeNone,
|
||||
bypassThrottling: true,
|
||||
bytesSaved: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tv := range tests {
|
||||
t.Run(tv.desc, func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
encodedMsg, err := mb.createOutbound(tv.msg, tv.compressionType, tv.bypassThrottling)
|
||||
require.NoError(err)
|
||||
|
||||
require.Equal(tv.bypassThrottling, encodedMsg.BypassThrottling())
|
||||
require.Equal(tv.op, encodedMsg.Op())
|
||||
|
||||
if bytesSaved := encodedMsg.BytesSavedCompression(); tv.bytesSaved {
|
||||
require.Positive(bytesSaved)
|
||||
}
|
||||
|
||||
parsedMsg, err := mb.parseInbound(encodedMsg.Bytes(), ids.EmptyNodeID, func() {})
|
||||
require.NoError(err)
|
||||
require.Equal(tv.op, parsedMsg.Op())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Tests the Stringer interface on inbound messages
|
||||
func TestInboundMessageToString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := require.New(t)
|
||||
|
||||
mb, err := newMsgBuilder(
|
||||
metric.NewRegistry(),
|
||||
5*time.Second,
|
||||
)
|
||||
require.NoError(err)
|
||||
|
||||
// msg that will become the tested InboundMessage
|
||||
msg := &p2p.Message{
|
||||
Message: &p2p.Message_Pong{
|
||||
Pong: &p2p.Pong{},
|
||||
},
|
||||
}
|
||||
msgBytes, err := p2p.Marshal(msg)
|
||||
require.NoError(err)
|
||||
|
||||
inboundMsg, err := mb.parseInbound(msgBytes, ids.EmptyNodeID, func() {})
|
||||
require.NoError(err)
|
||||
|
||||
// ZAP returns "Pong{Uptime:0}", proto returns empty string
|
||||
require.Contains(inboundMsg.String(), "NodeID-111111111111111111116DBWJs Op: pong Message:")
|
||||
|
||||
internalMsg := InternalGetStateSummaryFrontierFailed(ids.EmptyNodeID, ids.Empty, 1)
|
||||
require.Equal("NodeID-111111111111111111116DBWJs Op: get_state_summary_frontier_failed Message: ChainID: 11111111111111111111111111111111LpoYY RequestID: 1", internalMsg.String())
|
||||
}
|
||||
|
||||
func TestEmptyInboundMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := require.New(t)
|
||||
|
||||
mb, err := newMsgBuilder(
|
||||
metric.NewRegistry(),
|
||||
5*time.Second,
|
||||
)
|
||||
require.NoError(err)
|
||||
|
||||
msg := &p2p.Message{}
|
||||
msgBytes, err := p2p.Marshal(msg)
|
||||
// ZAP returns error at marshal time for empty message
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = mb.parseInbound(msgBytes, ids.EmptyNodeID, func() {})
|
||||
require.ErrorIs(err, errUnknownMessageType)
|
||||
}
|
||||
|
||||
func TestNilInboundMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := require.New(t)
|
||||
|
||||
mb, err := newMsgBuilder(
|
||||
metric.NewRegistry(),
|
||||
5*time.Second,
|
||||
)
|
||||
require.NoError(err)
|
||||
|
||||
msg := &p2p.Message{
|
||||
Message: &p2p.Message_Ping{
|
||||
Ping: nil,
|
||||
},
|
||||
}
|
||||
msgBytes, err := p2p.Marshal(msg)
|
||||
// ZAP returns error at marshal time for nil message content
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
parsedMsg, err := mb.parseInbound(msgBytes, ids.EmptyNodeID, func() {})
|
||||
require.NoError(err)
|
||||
|
||||
require.IsType(&p2p.Ping{}, parsedMsg.message)
|
||||
pingMsg := parsedMsg.message.(*p2p.Ping)
|
||||
require.NotNil(pingMsg)
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/luxfi/node/message (interfaces: OutboundMessage)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=message -destination=message/mock_message.go github.com/luxfi/node/message OutboundMessage
|
||||
//
|
||||
|
||||
// Package message is a generated GoMock package.
|
||||
package message
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/luxfi/mock/gomock"
|
||||
)
|
||||
|
||||
// MockOutboundMessage is a mock of OutboundMessage interface.
|
||||
type MockOutboundMessage struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockOutboundMessageMockRecorder
|
||||
}
|
||||
|
||||
// MockOutboundMessageMockRecorder is the mock recorder for MockOutboundMessage.
|
||||
type MockOutboundMessageMockRecorder struct {
|
||||
mock *MockOutboundMessage
|
||||
}
|
||||
|
||||
// NewMockOutboundMessage creates a new mock instance.
|
||||
func NewMockOutboundMessage(ctrl *gomock.Controller) *MockOutboundMessage {
|
||||
mock := &MockOutboundMessage{ctrl: ctrl}
|
||||
mock.recorder = &MockOutboundMessageMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockOutboundMessage) EXPECT() *MockOutboundMessageMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// BypassThrottling mocks base method.
|
||||
func (m *MockOutboundMessage) BypassThrottling() bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BypassThrottling")
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// BypassThrottling indicates an expected call of BypassThrottling.
|
||||
func (mr *MockOutboundMessageMockRecorder) BypassThrottling() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BypassThrottling", reflect.TypeOf((*MockOutboundMessage)(nil).BypassThrottling))
|
||||
}
|
||||
|
||||
// Bytes mocks base method.
|
||||
func (m *MockOutboundMessage) Bytes() []byte {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Bytes")
|
||||
ret0, _ := ret[0].([]byte)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Bytes indicates an expected call of Bytes.
|
||||
func (mr *MockOutboundMessageMockRecorder) Bytes() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bytes", reflect.TypeOf((*MockOutboundMessage)(nil).Bytes))
|
||||
}
|
||||
|
||||
// BytesSavedCompression mocks base method.
|
||||
func (m *MockOutboundMessage) BytesSavedCompression() int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BytesSavedCompression")
|
||||
ret0, _ := ret[0].(int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// BytesSavedCompression indicates an expected call of BytesSavedCompression.
|
||||
func (mr *MockOutboundMessageMockRecorder) BytesSavedCompression() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BytesSavedCompression", reflect.TypeOf((*MockOutboundMessage)(nil).BytesSavedCompression))
|
||||
}
|
||||
|
||||
// Op mocks base method.
|
||||
func (m *MockOutboundMessage) Op() Op {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Op")
|
||||
ret0, _ := ret[0].(Op)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Op indicates an expected call of Op.
|
||||
func (mr *MockOutboundMessageMockRecorder) Op() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Op", reflect.TypeOf((*MockOutboundMessage)(nil).Op))
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/luxfi/node/message (interfaces: OutboundMsgBuilder)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=message -destination=message/mock_outbound_message_builder.go github.com/luxfi/node/message OutboundMsgBuilder
|
||||
//
|
||||
|
||||
// Package message is a generated GoMock package.
|
||||
package message
|
||||
|
||||
import (
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
netip "net/netip"
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
|
||||
ids "github.com/luxfi/ids"
|
||||
p2p "github.com/luxfi/node/proto/p2p"
|
||||
"github.com/luxfi/net/endpoints"
|
||||
)
|
||||
|
||||
// MockOutboundMsgBuilder is a mock of OutboundMsgBuilder interface.
|
||||
type MockOutboundMsgBuilder struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockOutboundMsgBuilderMockRecorder
|
||||
}
|
||||
|
||||
// MockOutboundMsgBuilderMockRecorder is the mock recorder for MockOutboundMsgBuilder.
|
||||
type MockOutboundMsgBuilderMockRecorder struct {
|
||||
mock *MockOutboundMsgBuilder
|
||||
}
|
||||
|
||||
// NewMockOutboundMsgBuilder creates a new mock instance.
|
||||
func NewMockOutboundMsgBuilder(ctrl *gomock.Controller) *MockOutboundMsgBuilder {
|
||||
mock := &MockOutboundMsgBuilder{ctrl: ctrl}
|
||||
mock.recorder = &MockOutboundMsgBuilderMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockOutboundMsgBuilder) EXPECT() *MockOutboundMsgBuilderMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Accepted mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Accepted(arg0 ids.ID, arg1 uint32, arg2 []ids.ID) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Accepted", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Accepted indicates an expected call of Accepted.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Accepted(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accepted", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Accepted), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// AcceptedFrontier mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) AcceptedFrontier(arg0 ids.ID, arg1 uint32, arg2 ids.ID) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AcceptedFrontier", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AcceptedFrontier indicates an expected call of AcceptedFrontier.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) AcceptedFrontier(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).AcceptedFrontier), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// AcceptedStateSummary mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) AcceptedStateSummary(arg0 ids.ID, arg1 uint32, arg2 []ids.ID) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AcceptedStateSummary", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AcceptedStateSummary indicates an expected call of AcceptedStateSummary.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) AcceptedStateSummary(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedStateSummary", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).AcceptedStateSummary), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// Ancestors mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Ancestors(arg0 ids.ID, arg1 uint32, arg2 [][]byte) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Ancestors", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Ancestors indicates an expected call of Ancestors.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Ancestors(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ancestors", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Ancestors), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// Error mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Error(arg0 ids.ID, arg1 uint32, arg2 int32, arg3 string) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Error", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Error indicates an expected call of Error.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Error(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Error), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// Gossip mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Gossip(arg0 ids.ID, arg1 []byte) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Gossip", arg0, arg1)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Gossip indicates an expected call of Gossip.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Gossip(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Gossip", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Gossip), arg0, arg1)
|
||||
}
|
||||
|
||||
// Request mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Request(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 []byte) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Request", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Request indicates an expected call of Request.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Request(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Request", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Request), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// Response mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Response(arg0 ids.ID, arg1 uint32, arg2 []byte) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Response", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Response indicates an expected call of Response.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Response(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Response", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Response), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// Chits mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Chits(arg0 ids.ID, arg1 uint32, arg2, arg3, arg4 ids.ID) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Chits", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Chits indicates an expected call of Chits.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Chits(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chits", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Chits), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Get(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 ids.ID) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Get(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Get), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// GetAccepted mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) GetAccepted(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 []ids.ID) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAccepted", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAccepted indicates an expected call of GetAccepted.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) GetAccepted(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccepted", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAccepted), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// GetAcceptedFrontier mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) GetAcceptedFrontier(arg0 ids.ID, arg1 uint32, arg2 time.Duration) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAcceptedFrontier", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAcceptedFrontier indicates an expected call of GetAcceptedFrontier.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) GetAcceptedFrontier(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAcceptedFrontier), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// GetAcceptedStateSummary mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) GetAcceptedStateSummary(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 []uint64) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAcceptedStateSummary", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAcceptedStateSummary indicates an expected call of GetAcceptedStateSummary.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) GetAcceptedStateSummary(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedStateSummary", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAcceptedStateSummary), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// GetAncestors mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) GetAncestors(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 ids.ID, arg4 p2p.EngineType) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAncestors", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAncestors indicates an expected call of GetAncestors.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) GetAncestors(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAncestors", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAncestors), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// GetPeerList mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) GetPeerList(arg0, arg1 []byte) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPeerList", arg0, arg1)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetPeerList indicates an expected call of GetPeerList.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) GetPeerList(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPeerList", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetPeerList), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetStateSummaryFrontier mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) GetStateSummaryFrontier(arg0 ids.ID, arg1 uint32, arg2 time.Duration) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetStateSummaryFrontier", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetStateSummaryFrontier indicates an expected call of GetStateSummaryFrontier.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) GetStateSummaryFrontier(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateSummaryFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetStateSummaryFrontier), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// Handshake mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Handshake(arg0 uint32, arg1 uint64, arg2 netip.AddrPort, arg3 string, arg4, arg5, arg6 uint32, arg7 uint64, arg8, arg9 []byte, arg10 []ids.ID, arg11, arg12 []uint32, arg13, arg14 []byte) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Handshake", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Handshake indicates an expected call of Handshake.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Handshake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Handshake), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14)
|
||||
}
|
||||
|
||||
// PeerList mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) PeerList(arg0 []*endpoints.ClaimedIPPort, arg1 bool) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PeerList", arg0, arg1)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PeerList indicates an expected call of PeerList.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) PeerList(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerList", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).PeerList), arg0, arg1)
|
||||
}
|
||||
|
||||
// Ping mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Ping(arg0 uint32) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Ping", arg0)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Ping indicates an expected call of Ping.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Ping(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Ping), arg0, arg1)
|
||||
}
|
||||
|
||||
// Pong mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Pong() (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Pong")
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Pong indicates an expected call of Pong.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Pong() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pong", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Pong))
|
||||
}
|
||||
|
||||
// PullQuery mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) PullQuery(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 ids.ID, arg4 uint64) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PullQuery", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PullQuery indicates an expected call of PullQuery.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) PullQuery(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PullQuery", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).PullQuery), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// PushQuery mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) PushQuery(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 []byte, arg4 uint64) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PushQuery", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PushQuery indicates an expected call of PushQuery.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) PushQuery(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushQuery", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).PushQuery), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// Put mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) Put(arg0 ids.ID, arg1 uint32, arg2 []byte) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Put indicates an expected call of Put.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) Put(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Put), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// StateSummaryFrontier mocks base method.
|
||||
func (m *MockOutboundMsgBuilder) StateSummaryFrontier(arg0 ids.ID, arg1 uint32, arg2 []byte) (OutboundMessage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "StateSummaryFrontier", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(OutboundMessage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// StateSummaryFrontier indicates an expected call of StateSummaryFrontier.
|
||||
func (mr *MockOutboundMsgBuilderMockRecorder) StateSummaryFrontier(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).StateSummaryFrontier), arg0, arg1, arg2)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/outbound_message.go -mock_names=OutboundMessage=OutboundMessage . OutboundMessage
|
||||
//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/outbound_message_builder.go -mock_names=OutboundMsgBuilder=OutboundMsgBuilder . OutboundMsgBuilder
|
||||
+403
@@ -0,0 +1,403 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/luxfi/math/set"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
)
|
||||
|
||||
// Op is an opcode
|
||||
type Op byte
|
||||
|
||||
// Types of messages that may be sent between nodes
|
||||
// Note: If you add a new parseable Op below, you must add it to either
|
||||
// [UnrequestedOps] or [FailedToResponseOps].
|
||||
const (
|
||||
// Handshake:
|
||||
PingOp Op = iota
|
||||
PongOp
|
||||
HandshakeOp
|
||||
GetPeerListOp
|
||||
PeerListOp
|
||||
// State sync:
|
||||
GetStateSummaryFrontierOp
|
||||
GetStateSummaryFrontierFailedOp
|
||||
StateSummaryFrontierOp
|
||||
GetAcceptedStateSummaryOp
|
||||
GetAcceptedStateSummaryFailedOp
|
||||
AcceptedStateSummaryOp
|
||||
// Bootstrapping:
|
||||
GetAcceptedFrontierOp
|
||||
GetAcceptedFrontierFailedOp
|
||||
AcceptedFrontierOp
|
||||
GetAcceptedOp
|
||||
GetAcceptedFailedOp
|
||||
AcceptedOp
|
||||
GetAncestorsOp
|
||||
GetAncestorsFailedOp
|
||||
AncestorsOp
|
||||
// Consensus:
|
||||
GetOp
|
||||
GetFailedOp
|
||||
PutOp
|
||||
PushQueryOp
|
||||
PullQueryOp
|
||||
QueryFailedOp
|
||||
QbitOp // Authenticated preference signal (formerly ChitsOp)
|
||||
// Application:
|
||||
RequestOp
|
||||
ErrorOp
|
||||
ResponseOp
|
||||
GossipOp
|
||||
// Internal:
|
||||
ConnectedOp
|
||||
DisconnectedOp
|
||||
NotifyOp
|
||||
GossipRequestOp
|
||||
// BFT
|
||||
BFTOp
|
||||
)
|
||||
|
||||
var (
|
||||
// UnrequestedOps are operations that are expected to be seen without having
|
||||
// requested them. For example, a peer may receive a Get request for a block
|
||||
// without having sent a message previously.
|
||||
UnrequestedOps = set.Of(
|
||||
GetAcceptedFrontierOp,
|
||||
GetAcceptedOp,
|
||||
GetAncestorsOp,
|
||||
GetOp,
|
||||
PushQueryOp,
|
||||
PullQueryOp,
|
||||
RequestOp,
|
||||
GossipOp,
|
||||
GetStateSummaryFrontierOp,
|
||||
GetAcceptedStateSummaryOp,
|
||||
BFTOp,
|
||||
)
|
||||
// FailedToResponseOps maps response failure messages to their successful
|
||||
// counterparts.
|
||||
FailedToResponseOps = map[Op]Op{
|
||||
GetStateSummaryFrontierFailedOp: StateSummaryFrontierOp,
|
||||
GetAcceptedStateSummaryFailedOp: AcceptedStateSummaryOp,
|
||||
GetAcceptedFrontierFailedOp: AcceptedFrontierOp,
|
||||
GetAcceptedFailedOp: AcceptedOp,
|
||||
GetAncestorsFailedOp: AncestorsOp,
|
||||
GetFailedOp: PutOp,
|
||||
QueryFailedOp: QbitOp,
|
||||
ErrorOp: ResponseOp,
|
||||
}
|
||||
|
||||
errUnknownMessageType = errors.New("unknown message type")
|
||||
)
|
||||
|
||||
func (op Op) String() string {
|
||||
switch op {
|
||||
// Handshake
|
||||
case PingOp:
|
||||
return "ping"
|
||||
case PongOp:
|
||||
return "pong"
|
||||
case HandshakeOp:
|
||||
return "handshake"
|
||||
case GetPeerListOp:
|
||||
return "get_peerlist"
|
||||
case PeerListOp:
|
||||
return "peerlist"
|
||||
// State sync
|
||||
case GetStateSummaryFrontierOp:
|
||||
return "get_state_summary_frontier"
|
||||
case GetStateSummaryFrontierFailedOp:
|
||||
return "get_state_summary_frontier_failed"
|
||||
case StateSummaryFrontierOp:
|
||||
return "state_summary_frontier"
|
||||
case GetAcceptedStateSummaryOp:
|
||||
return "get_accepted_state_summary"
|
||||
case GetAcceptedStateSummaryFailedOp:
|
||||
return "get_accepted_state_summary_failed"
|
||||
case AcceptedStateSummaryOp:
|
||||
return "accepted_state_summary"
|
||||
// Bootstrapping
|
||||
case GetAcceptedFrontierOp:
|
||||
return "get_accepted_frontier"
|
||||
case GetAcceptedFrontierFailedOp:
|
||||
return "get_accepted_frontier_failed"
|
||||
case AcceptedFrontierOp:
|
||||
return "accepted_frontier"
|
||||
case GetAcceptedOp:
|
||||
return "get_accepted"
|
||||
case GetAcceptedFailedOp:
|
||||
return "get_accepted_failed"
|
||||
case AcceptedOp:
|
||||
return "accepted"
|
||||
case GetAncestorsOp:
|
||||
return "get_ancestors"
|
||||
case GetAncestorsFailedOp:
|
||||
return "get_ancestors_failed"
|
||||
case AncestorsOp:
|
||||
return "ancestors"
|
||||
// Consensus
|
||||
case GetOp:
|
||||
return "get"
|
||||
case GetFailedOp:
|
||||
return "get_failed"
|
||||
case PutOp:
|
||||
return "put"
|
||||
case PushQueryOp:
|
||||
return "push_query"
|
||||
case PullQueryOp:
|
||||
return "pull_query"
|
||||
case QueryFailedOp:
|
||||
return "query_failed"
|
||||
case QbitOp:
|
||||
return "qbit"
|
||||
// Application
|
||||
case RequestOp:
|
||||
return "app_request"
|
||||
case ErrorOp:
|
||||
return "app_error"
|
||||
case ResponseOp:
|
||||
return "app_response"
|
||||
case GossipOp:
|
||||
return "app_gossip"
|
||||
// Internal
|
||||
case ConnectedOp:
|
||||
return "connected"
|
||||
case DisconnectedOp:
|
||||
return "disconnected"
|
||||
case NotifyOp:
|
||||
return "notify"
|
||||
case GossipRequestOp:
|
||||
return "gossip_request"
|
||||
// BFT
|
||||
case BFTOp:
|
||||
return "bft"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func Unwrap(m *p2p.Message) (fmt.Stringer, error) {
|
||||
switch msg := m.GetMessage().(type) {
|
||||
// Handshake:
|
||||
case *p2p.Message_Ping:
|
||||
return msg.Ping, nil
|
||||
case *p2p.Message_Pong:
|
||||
return msg.Pong, nil
|
||||
case *p2p.Message_Handshake:
|
||||
return msg.Handshake, nil
|
||||
case *p2p.Message_GetPeerList:
|
||||
return msg.GetPeerList, nil
|
||||
case *p2p.Message_PeerList_:
|
||||
return msg.PeerList_, nil
|
||||
// State sync:
|
||||
case *p2p.Message_GetStateSummaryFrontier:
|
||||
return msg.GetStateSummaryFrontier, nil
|
||||
case *p2p.Message_StateSummaryFrontier_:
|
||||
return msg.StateSummaryFrontier_, nil
|
||||
case *p2p.Message_GetAcceptedStateSummary:
|
||||
return msg.GetAcceptedStateSummary, nil
|
||||
case *p2p.Message_AcceptedStateSummary_:
|
||||
return msg.AcceptedStateSummary_, nil
|
||||
// Bootstrapping:
|
||||
case *p2p.Message_GetAcceptedFrontier:
|
||||
return msg.GetAcceptedFrontier, nil
|
||||
case *p2p.Message_AcceptedFrontier_:
|
||||
return msg.AcceptedFrontier_, nil
|
||||
case *p2p.Message_GetAccepted:
|
||||
return msg.GetAccepted, nil
|
||||
case *p2p.Message_Accepted_:
|
||||
return msg.Accepted_, nil
|
||||
case *p2p.Message_GetAncestors:
|
||||
return msg.GetAncestors, nil
|
||||
case *p2p.Message_Ancestors_:
|
||||
return msg.Ancestors_, nil
|
||||
// Consensus:
|
||||
case *p2p.Message_Get:
|
||||
return msg.Get, nil
|
||||
case *p2p.Message_Put:
|
||||
return msg.Put, nil
|
||||
case *p2p.Message_PushQuery:
|
||||
return msg.PushQuery, nil
|
||||
case *p2p.Message_PullQuery:
|
||||
return msg.PullQuery, nil
|
||||
case *p2p.Message_Chits:
|
||||
return msg.Chits, nil
|
||||
// Application:
|
||||
case *p2p.Message_Request:
|
||||
return msg.Request, nil
|
||||
case *p2p.Message_Response:
|
||||
return msg.Response, nil
|
||||
case *p2p.Message_Error:
|
||||
return msg.Error, nil
|
||||
case *p2p.Message_Gossip:
|
||||
return msg.Gossip, nil
|
||||
// BFT
|
||||
case *p2p.Message_BFT:
|
||||
return extractBFT(msg), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("%w: %T", errUnknownMessageType, msg)
|
||||
}
|
||||
}
|
||||
|
||||
// ToConsensusOp maps message.Op to consensus router Op values
|
||||
// Returns the consensus Op value and whether the mapping exists
|
||||
func ToConsensusOp(op Op) (byte, bool) {
|
||||
switch op {
|
||||
case GetAcceptedFrontierOp:
|
||||
return 0, true // GetAcceptedFrontier
|
||||
case AcceptedFrontierOp:
|
||||
return 1, true // AcceptedFrontier
|
||||
case GetAcceptedOp:
|
||||
return 2, true // GetAccepted
|
||||
case AcceptedOp:
|
||||
return 3, true // Accepted
|
||||
case GetOp:
|
||||
return 4, true // Get
|
||||
case PutOp:
|
||||
return 5, true // Put
|
||||
case PushQueryOp:
|
||||
return 6, true // PushQuery
|
||||
case PullQueryOp:
|
||||
return 7, true // PullQuery
|
||||
case QbitOp:
|
||||
return 8, true // Qbit
|
||||
case GetAncestorsOp:
|
||||
return 9, true // GetContext (wire protocol still uses GetAncestors)
|
||||
case AncestorsOp:
|
||||
return 10, true // Context (wire protocol still uses Ancestors)
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
// GetContainerBytes extracts the container/body bytes from various message types
|
||||
func GetContainerBytes(msg fmt.Stringer) []byte {
|
||||
switch m := msg.(type) {
|
||||
case *p2p.Put:
|
||||
return m.Container
|
||||
case *p2p.PushQuery:
|
||||
return m.Container
|
||||
case *p2p.Ancestors:
|
||||
// Encode all containers with length prefix so handlers can decode
|
||||
// multiple blocks from a single byte slice.
|
||||
if len(m.Containers) == 0 {
|
||||
return nil
|
||||
}
|
||||
totalLen := 0
|
||||
for _, container := range m.Containers {
|
||||
totalLen += 4 + len(container)
|
||||
}
|
||||
encoded := make([]byte, 0, totalLen)
|
||||
for _, container := range m.Containers {
|
||||
var lenBuf [4]byte
|
||||
binary.BigEndian.PutUint32(lenBuf[:], uint32(len(container)))
|
||||
encoded = append(encoded, lenBuf[:]...)
|
||||
encoded = append(encoded, container...)
|
||||
}
|
||||
return encoded
|
||||
case *p2p.Gossip:
|
||||
return m.AppBytes
|
||||
case *p2p.Request:
|
||||
return m.AppBytes
|
||||
case *p2p.Response:
|
||||
return m.AppBytes
|
||||
// Request messages with container IDs for P-Chain sync
|
||||
case *p2p.GetAccepted:
|
||||
containerIDs := m.GetContainerIds()
|
||||
if len(containerIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
result := make([]byte, 0, len(containerIDs)*32)
|
||||
for _, id := range containerIDs {
|
||||
result = append(result, id...)
|
||||
}
|
||||
return result
|
||||
case *p2p.Get:
|
||||
return m.GetContainerId()
|
||||
case *p2p.GetAncestors:
|
||||
return m.GetContainerId()
|
||||
case *p2p.PullQuery:
|
||||
return m.GetContainerId()
|
||||
case *p2p.Chits:
|
||||
// For Qbit messages (formerly Chits), return the PreferredId (the block being voted for)
|
||||
return m.GetPreferredId()
|
||||
case *p2p.AcceptedFrontier:
|
||||
return m.GetContainerId()
|
||||
case *p2p.Accepted:
|
||||
containerIDs := m.GetContainerIds()
|
||||
if len(containerIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
result := make([]byte, 0, len(containerIDs)*32)
|
||||
for _, id := range containerIDs {
|
||||
result = append(result, id...)
|
||||
}
|
||||
return result
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ToOp(m *p2p.Message) (Op, error) {
|
||||
switch msg := m.GetMessage().(type) {
|
||||
case *p2p.Message_Ping:
|
||||
return PingOp, nil
|
||||
case *p2p.Message_Pong:
|
||||
return PongOp, nil
|
||||
case *p2p.Message_Handshake:
|
||||
return HandshakeOp, nil
|
||||
case *p2p.Message_GetPeerList:
|
||||
return GetPeerListOp, nil
|
||||
case *p2p.Message_PeerList_:
|
||||
return PeerListOp, nil
|
||||
case *p2p.Message_GetStateSummaryFrontier:
|
||||
return GetStateSummaryFrontierOp, nil
|
||||
case *p2p.Message_StateSummaryFrontier_:
|
||||
return StateSummaryFrontierOp, nil
|
||||
case *p2p.Message_GetAcceptedStateSummary:
|
||||
return GetAcceptedStateSummaryOp, nil
|
||||
case *p2p.Message_AcceptedStateSummary_:
|
||||
return AcceptedStateSummaryOp, nil
|
||||
case *p2p.Message_GetAcceptedFrontier:
|
||||
return GetAcceptedFrontierOp, nil
|
||||
case *p2p.Message_AcceptedFrontier_:
|
||||
return AcceptedFrontierOp, nil
|
||||
case *p2p.Message_GetAccepted:
|
||||
return GetAcceptedOp, nil
|
||||
case *p2p.Message_Accepted_:
|
||||
return AcceptedOp, nil
|
||||
case *p2p.Message_GetAncestors:
|
||||
return GetAncestorsOp, nil
|
||||
case *p2p.Message_Ancestors_:
|
||||
return AncestorsOp, nil
|
||||
case *p2p.Message_Get:
|
||||
return GetOp, nil
|
||||
case *p2p.Message_Put:
|
||||
return PutOp, nil
|
||||
case *p2p.Message_PushQuery:
|
||||
return PushQueryOp, nil
|
||||
case *p2p.Message_PullQuery:
|
||||
return PullQueryOp, nil
|
||||
case *p2p.Message_Chits:
|
||||
return QbitOp, nil
|
||||
case *p2p.Message_Request:
|
||||
return RequestOp, nil
|
||||
case *p2p.Message_Response:
|
||||
return ResponseOp, nil
|
||||
case *p2p.Message_Error:
|
||||
return ErrorOp, nil
|
||||
case *p2p.Message_Gossip:
|
||||
return GossipOp, nil
|
||||
case *p2p.Message_BFT:
|
||||
return BFTOp, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("%w: %T", errUnknownMessageType, msg)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,752 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
compression "github.com/luxfi/compress"
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/net/endpoints"
|
||||
"github.com/luxfi/node/proto/p2p"
|
||||
)
|
||||
|
||||
var _ OutboundMsgBuilder = (*outMsgBuilder)(nil)
|
||||
|
||||
// OutboundMsgBuilder builds outbound messages. Outbound messages are returned
|
||||
// with a reference count of 1. Once the reference count hits 0, the message
|
||||
// bytes should no longer be accessed.
|
||||
type OutboundMsgBuilder interface {
|
||||
Handshake(
|
||||
networkID uint32,
|
||||
myTime uint64,
|
||||
ip netip.AddrPort,
|
||||
client string,
|
||||
major uint32,
|
||||
minor uint32,
|
||||
patch uint32,
|
||||
ipSigningTime uint64,
|
||||
ipNodeIDSig []byte,
|
||||
ipBLSSig []byte,
|
||||
trackedNets []ids.ID,
|
||||
supportedLPs []uint32,
|
||||
objectedLPs []uint32,
|
||||
knownPeersFilter []byte,
|
||||
knownPeersSalt []byte,
|
||||
requestAllNetIPs bool,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
GetPeerList(
|
||||
knownPeersFilter []byte,
|
||||
knownPeersSalt []byte,
|
||||
requestAllNetIPs bool,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
PeerList(
|
||||
peers []*endpoints.ClaimedIPPort,
|
||||
bypassThrottling bool,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Ping(
|
||||
primaryUptime uint32,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Pong() (OutboundMessage, error)
|
||||
|
||||
GetStateSummaryFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
StateSummaryFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
summary []byte,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
GetAcceptedStateSummary(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
heights []uint64,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
AcceptedStateSummary(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
summaryIDs []ids.ID,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
GetAcceptedFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
AcceptedFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
containerID ids.ID,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
GetAccepted(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerIDs []ids.ID,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Accepted(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
containerIDs []ids.ID,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
GetAncestors(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerID ids.ID,
|
||||
engineType p2p.EngineType,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Ancestors(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
containers [][]byte,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Get(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerID ids.ID,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Put(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
container []byte,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
PushQuery(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
container []byte,
|
||||
requestedHeight uint64,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
PullQuery(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerID ids.ID,
|
||||
requestedHeight uint64,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Chits(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
preferredID ids.ID,
|
||||
preferredIDAtHeight ids.ID,
|
||||
acceptedID ids.ID,
|
||||
acceptedHeight uint64,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Request(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
msg []byte,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Response(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
msg []byte,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Error(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
errorCode int32,
|
||||
errorMessage string,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
Gossip(
|
||||
chainID ids.ID,
|
||||
msg []byte,
|
||||
) (OutboundMessage, error)
|
||||
|
||||
BFTMessage(
|
||||
msg *p2p.BFT,
|
||||
) (OutboundMessage, error)
|
||||
}
|
||||
|
||||
type outMsgBuilder struct {
|
||||
compressionType compression.Type
|
||||
|
||||
builder *msgBuilder
|
||||
}
|
||||
|
||||
// Use "message.NewCreator" to import this function
|
||||
// since we do not expose "msgBuilder" yet
|
||||
func newOutboundBuilder(compressionType compression.Type, builder *msgBuilder) OutboundMsgBuilder {
|
||||
return &outMsgBuilder{
|
||||
compressionType: compressionType,
|
||||
builder: builder,
|
||||
}
|
||||
}
|
||||
|
||||
// ... ping/pong omitted for brevity in prompt, only replacing targeted section ...
|
||||
// Wait, replace_file_content replaces a chunk. I need to target the Interface definitions and Implementation.
|
||||
// Interface is lines 160-188.
|
||||
// Implementation is lines 663-731.
|
||||
// I should use 2 ReplaceFile calls or one if contiguous? They are NOT contiguous.
|
||||
// I can use `multi_replace_file_content`? Or `replace_file_content` twice.
|
||||
// I'll do Interface first.
|
||||
// Oh wait, `replace_file_content` only allows ONE chunk.
|
||||
// I'll use separate calls or `multi_replace`.
|
||||
// I'll use `multi_replace_file_content` for `outbound_msg_builder.go`.
|
||||
|
||||
func (b *outMsgBuilder) Ping(
|
||||
primaryUptime uint32,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Ping{
|
||||
Ping: &p2p.Ping{
|
||||
Uptime: primaryUptime,
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Pong() (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Pong{
|
||||
Pong: &p2p.Pong{},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Handshake(
|
||||
networkID uint32,
|
||||
myTime uint64,
|
||||
ip netip.AddrPort,
|
||||
client string,
|
||||
major uint32,
|
||||
minor uint32,
|
||||
patch uint32,
|
||||
ipSigningTime uint64,
|
||||
ipNodeIDSig []byte,
|
||||
ipBLSSig []byte,
|
||||
trackedNets []ids.ID,
|
||||
supportedLPs []uint32,
|
||||
objectedLPs []uint32,
|
||||
knownPeersFilter []byte,
|
||||
knownPeersSalt []byte,
|
||||
requestAllNetIPs bool,
|
||||
) (OutboundMessage, error) {
|
||||
subsubchainIDBytes := make([][]byte, len(trackedNets))
|
||||
encodeIDs(trackedNets, subsubchainIDBytes)
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Handshake{
|
||||
Handshake: &p2p.Handshake{
|
||||
NetworkId: networkID,
|
||||
MyTime: myTime,
|
||||
IpAddr: ip.Addr().AsSlice(),
|
||||
IpPort: uint32(ip.Port()),
|
||||
IpSigningTime: ipSigningTime,
|
||||
IpNodeIdSig: ipNodeIDSig,
|
||||
TrackedNets: subsubchainIDBytes,
|
||||
Client: &p2p.Client{
|
||||
Name: client,
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
Patch: patch,
|
||||
},
|
||||
SupportedLps: supportedLPs,
|
||||
ObjectedLps: objectedLPs,
|
||||
KnownPeers: &p2p.BloomFilter{
|
||||
Filter: knownPeersFilter,
|
||||
Salt: knownPeersSalt,
|
||||
},
|
||||
IpBlsSig: ipBLSSig,
|
||||
AllChains: requestAllNetIPs,
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) GetPeerList(
|
||||
knownPeersFilter []byte,
|
||||
knownPeersSalt []byte,
|
||||
requestAllNetIPs bool,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_GetPeerList{
|
||||
GetPeerList: &p2p.GetPeerList{
|
||||
KnownPeers: &p2p.BloomFilter{
|
||||
Filter: knownPeersFilter,
|
||||
Salt: knownPeersSalt,
|
||||
},
|
||||
AllChains: requestAllNetIPs,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) PeerList(peers []*endpoints.ClaimedIPPort, bypassThrottling bool) (OutboundMessage, error) {
|
||||
claimIPPorts := make([]*p2p.ClaimedIpPort, len(peers))
|
||||
for i, p := range peers {
|
||||
claimIPPorts[i] = &p2p.ClaimedIpPort{
|
||||
X509Certificate: p.Cert.Raw,
|
||||
IpAddr: p.AddrPort.Addr().AsSlice(),
|
||||
IpPort: uint32(p.AddrPort.Port()),
|
||||
Timestamp: p.Timestamp,
|
||||
Signature: p.Signature,
|
||||
TxId: ids.Empty[:],
|
||||
}
|
||||
}
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_PeerList_{
|
||||
PeerList_: &p2p.PeerList{
|
||||
ClaimedIpPorts: claimIPPorts,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
bypassThrottling,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) GetStateSummaryFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_GetStateSummaryFrontier{
|
||||
GetStateSummaryFrontier: &p2p.GetStateSummaryFrontier{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) StateSummaryFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
summary []byte,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_StateSummaryFrontier_{
|
||||
StateSummaryFrontier_: &p2p.StateSummaryFrontier{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Summary: summary,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) GetAcceptedStateSummary(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
heights []uint64,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_GetAcceptedStateSummary{
|
||||
GetAcceptedStateSummary: &p2p.GetAcceptedStateSummary{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
Heights: heights,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) AcceptedStateSummary(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
summaryIDs []ids.ID,
|
||||
) (OutboundMessage, error) {
|
||||
summaryIDBytes := make([][]byte, len(summaryIDs))
|
||||
encodeIDs(summaryIDs, summaryIDBytes)
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_AcceptedStateSummary_{
|
||||
AcceptedStateSummary_: &p2p.AcceptedStateSummary{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
SummaryIds: summaryIDBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) GetAcceptedFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_GetAcceptedFrontier{
|
||||
GetAcceptedFrontier: &p2p.GetAcceptedFrontier{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) AcceptedFrontier(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
containerID ids.ID,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_AcceptedFrontier_{
|
||||
AcceptedFrontier_: &p2p.AcceptedFrontier{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
ContainerId: containerID[:],
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) GetAccepted(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerIDs []ids.ID,
|
||||
) (OutboundMessage, error) {
|
||||
containerIDBytes := make([][]byte, len(containerIDs))
|
||||
encodeIDs(containerIDs, containerIDBytes)
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_GetAccepted{
|
||||
GetAccepted: &p2p.GetAccepted{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
ContainerIds: containerIDBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Accepted(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
containerIDs []ids.ID,
|
||||
) (OutboundMessage, error) {
|
||||
containerIDBytes := make([][]byte, len(containerIDs))
|
||||
encodeIDs(containerIDs, containerIDBytes)
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Accepted_{
|
||||
Accepted_: &p2p.Accepted{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
ContainerIds: containerIDBytes,
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) GetAncestors(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerID ids.ID,
|
||||
engineType p2p.EngineType,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_GetAncestors{
|
||||
GetAncestors: &p2p.GetAncestors{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
ContainerId: containerID[:],
|
||||
EngineType: engineType,
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Ancestors(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
containers [][]byte,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Ancestors_{
|
||||
Ancestors_: &p2p.Ancestors{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Containers: containers,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Get(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerID ids.ID,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Get{
|
||||
Get: &p2p.Get{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
ContainerId: containerID[:],
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Put(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
container []byte,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Put{
|
||||
Put: &p2p.Put{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Container: container,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) PushQuery(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
container []byte,
|
||||
requestedHeight uint64,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_PushQuery{
|
||||
PushQuery: &p2p.PushQuery{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
Container: container,
|
||||
RequestedHeight: requestedHeight,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) PullQuery(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
containerID ids.ID,
|
||||
requestedHeight uint64,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_PullQuery{
|
||||
PullQuery: &p2p.PullQuery{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
ContainerId: containerID[:],
|
||||
RequestedHeight: requestedHeight,
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Chits(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
preferredID ids.ID,
|
||||
preferredIDAtHeight ids.ID,
|
||||
acceptedID ids.ID,
|
||||
acceptedHeight uint64,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Chits{
|
||||
Chits: &p2p.Chits{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
PreferredId: preferredID[:],
|
||||
PreferredIdAtHeight: preferredIDAtHeight[:],
|
||||
AcceptedId: acceptedID[:],
|
||||
AcceptedHeight: acceptedHeight,
|
||||
},
|
||||
},
|
||||
},
|
||||
compression.TypeNone,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Request(
|
||||
chainID ids.ID,
|
||||
requestID uint32,
|
||||
deadline time.Duration,
|
||||
msg []byte,
|
||||
) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Request{
|
||||
Request: &p2p.Request{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
Deadline: uint64(deadline),
|
||||
AppBytes: msg,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Response(chainID ids.ID, requestID uint32, msg []byte) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Response{
|
||||
Response: &p2p.Response{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
AppBytes: msg,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Error(chainID ids.ID, requestID uint32, errorCode int32, errorMessage string) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Error{
|
||||
Error: &p2p.Error{
|
||||
ChainId: chainID[:],
|
||||
RequestId: requestID,
|
||||
ErrorCode: errorCode,
|
||||
ErrorMessage: errorMessage,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) Gossip(chainID ids.ID, msg []byte) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: &p2p.Message_Gossip{
|
||||
Gossip: &p2p.Gossip{
|
||||
ChainId: chainID[:],
|
||||
AppBytes: msg,
|
||||
},
|
||||
},
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *outMsgBuilder) BFTMessage(msg *p2p.BFT) (OutboundMessage, error) {
|
||||
return b.builder.createOutbound(
|
||||
&p2p.Message{
|
||||
Message: newMessageBFT(msg),
|
||||
},
|
||||
b.compressionType,
|
||||
false,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
compression "github.com/luxfi/compress"
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/metric"
|
||||
)
|
||||
|
||||
func Test_newOutboundBuilder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mb, err := newMsgBuilder(
|
||||
metric.NewRegistry(),
|
||||
10*time.Second,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, compressionType := range []compression.Type{
|
||||
compression.TypeNone,
|
||||
compression.TypeZstd,
|
||||
} {
|
||||
t.Run(compressionType.String(), func(t *testing.T) {
|
||||
builder := newOutboundBuilder(compressionType, mb)
|
||||
|
||||
outMsg, err := builder.GetAcceptedStateSummary(
|
||||
ids.GenerateTestID(),
|
||||
12345,
|
||||
time.Hour,
|
||||
[]uint64{1000, 2000},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
t.Logf("outbound message with compression type %s built message with size %d", compressionType, len(outMsg.Bytes()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
// Package wire defines P2P message types for network communication.
|
||||
// This package is wire-format agnostic - encoding is handled by the parent message package.
|
||||
package wire
|
||||
|
||||
// EngineType represents the consensus engine type
|
||||
type EngineType int32
|
||||
|
||||
const (
|
||||
EngineType_UNSPECIFIED EngineType = 0
|
||||
EngineType_CHAIN EngineType = 1
|
||||
EngineType_DAG EngineType = 2
|
||||
)
|
||||
|
||||
// Message is the top-level P2P message container
|
||||
type Message struct {
|
||||
// Only one of these should be set
|
||||
CompressedZstd []byte
|
||||
Ping *Ping
|
||||
Pong *Pong
|
||||
Handshake *Handshake
|
||||
GetPeerList *GetPeerList
|
||||
PeerList *PeerList
|
||||
GetStateSummaryFrontier *GetStateSummaryFrontier
|
||||
StateSummaryFrontier *StateSummaryFrontier
|
||||
GetAcceptedStateSummary *GetAcceptedStateSummary
|
||||
AcceptedStateSummary *AcceptedStateSummary
|
||||
GetAcceptedFrontier *GetAcceptedFrontier
|
||||
AcceptedFrontier *AcceptedFrontier
|
||||
GetAccepted *GetAccepted
|
||||
Accepted *Accepted
|
||||
GetAncestors *GetAncestors
|
||||
Ancestors *Ancestors
|
||||
Get *Get
|
||||
Put *Put
|
||||
PushQuery *PushQuery
|
||||
PullQuery *PullQuery
|
||||
Chits *Chits
|
||||
Request *Request
|
||||
Response *Response
|
||||
Gossip *Gossip
|
||||
BFT *BFT
|
||||
}
|
||||
|
||||
// Ping message
|
||||
type Ping struct {
|
||||
Uptime uint32
|
||||
ChainSubnetPairs []*ChainSubnetPair
|
||||
}
|
||||
|
||||
// ChainSubnetPair for ping
|
||||
type ChainSubnetPair struct {
|
||||
ChainId []byte
|
||||
SubnetId []byte
|
||||
}
|
||||
|
||||
// Pong message
|
||||
type Pong struct {
|
||||
Uptime uint32
|
||||
ChainSubnetPairs []*ChainSubnetPair
|
||||
}
|
||||
|
||||
// Handshake message
|
||||
type Handshake struct {
|
||||
NetworkId uint32
|
||||
MyTime uint64
|
||||
IpAddr []byte
|
||||
IpPort uint32
|
||||
IpSigningTime uint64
|
||||
IpNodeIdSig []byte
|
||||
TrackedSubnets [][]byte
|
||||
Client *Client
|
||||
SupportedAcps []uint32
|
||||
ObjectedAcps []uint32
|
||||
KnownPeers *BloomFilter
|
||||
IpBlsSig []byte
|
||||
}
|
||||
|
||||
// Client info in handshake
|
||||
type Client struct {
|
||||
Name string
|
||||
Major uint32
|
||||
Minor uint32
|
||||
Patch uint32
|
||||
}
|
||||
|
||||
// BloomFilter for peer discovery
|
||||
type BloomFilter struct {
|
||||
Filter []byte
|
||||
Salt []byte
|
||||
}
|
||||
|
||||
// GetPeerList message
|
||||
type GetPeerList struct {
|
||||
KnownPeers *BloomFilter
|
||||
}
|
||||
|
||||
// PeerList message
|
||||
type PeerList struct {
|
||||
ClaimedIpPorts []*ClaimedIpPort
|
||||
}
|
||||
|
||||
// ClaimedIpPort in peer list
|
||||
type ClaimedIpPort struct {
|
||||
X509Certificate []byte
|
||||
IpAddr []byte
|
||||
IpPort uint32
|
||||
Timestamp uint64
|
||||
Signature []byte
|
||||
TxId []byte
|
||||
}
|
||||
|
||||
// GetStateSummaryFrontier message
|
||||
type GetStateSummaryFrontier struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
}
|
||||
|
||||
func (m *GetStateSummaryFrontier) GetChainId() []byte { return m.ChainId }
|
||||
func (m *GetStateSummaryFrontier) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *GetStateSummaryFrontier) GetDeadline() uint64 { return m.Deadline }
|
||||
|
||||
// StateSummaryFrontier message
|
||||
type StateSummaryFrontier struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Summary []byte
|
||||
}
|
||||
|
||||
func (m *StateSummaryFrontier) GetChainId() []byte { return m.ChainId }
|
||||
func (m *StateSummaryFrontier) GetRequestId() uint32 { return m.RequestId }
|
||||
|
||||
// GetAcceptedStateSummary message
|
||||
type GetAcceptedStateSummary struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
Heights []uint64
|
||||
}
|
||||
|
||||
func (m *GetAcceptedStateSummary) GetChainId() []byte { return m.ChainId }
|
||||
func (m *GetAcceptedStateSummary) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *GetAcceptedStateSummary) GetDeadline() uint64 { return m.Deadline }
|
||||
|
||||
// AcceptedStateSummary message
|
||||
type AcceptedStateSummary struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
SummaryIds [][]byte
|
||||
}
|
||||
|
||||
func (m *AcceptedStateSummary) GetChainId() []byte { return m.ChainId }
|
||||
func (m *AcceptedStateSummary) GetRequestId() uint32 { return m.RequestId }
|
||||
|
||||
// GetAcceptedFrontier message
|
||||
type GetAcceptedFrontier struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
EngineType EngineType
|
||||
}
|
||||
|
||||
func (m *GetAcceptedFrontier) GetChainId() []byte { return m.ChainId }
|
||||
func (m *GetAcceptedFrontier) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *GetAcceptedFrontier) GetDeadline() uint64 { return m.Deadline }
|
||||
|
||||
// AcceptedFrontier message
|
||||
type AcceptedFrontier struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
ContainerId []byte
|
||||
}
|
||||
|
||||
func (m *AcceptedFrontier) GetChainId() []byte { return m.ChainId }
|
||||
func (m *AcceptedFrontier) GetRequestId() uint32 { return m.RequestId }
|
||||
|
||||
// GetAccepted message
|
||||
type GetAccepted struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
ContainerIds [][]byte
|
||||
EngineType EngineType
|
||||
}
|
||||
|
||||
func (m *GetAccepted) GetChainId() []byte { return m.ChainId }
|
||||
func (m *GetAccepted) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *GetAccepted) GetDeadline() uint64 { return m.Deadline }
|
||||
|
||||
// Accepted message
|
||||
type Accepted struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
ContainerIds [][]byte
|
||||
}
|
||||
|
||||
func (m *Accepted) GetChainId() []byte { return m.ChainId }
|
||||
func (m *Accepted) GetRequestId() uint32 { return m.RequestId }
|
||||
|
||||
// GetAncestors message
|
||||
type GetAncestors struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
ContainerId []byte
|
||||
EngineType EngineType
|
||||
}
|
||||
|
||||
func (m *GetAncestors) GetChainId() []byte { return m.ChainId }
|
||||
func (m *GetAncestors) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *GetAncestors) GetDeadline() uint64 { return m.Deadline }
|
||||
func (m *GetAncestors) GetEngineType() EngineType { return m.EngineType }
|
||||
|
||||
// Ancestors message
|
||||
type Ancestors struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Containers [][]byte
|
||||
}
|
||||
|
||||
func (m *Ancestors) GetChainId() []byte { return m.ChainId }
|
||||
func (m *Ancestors) GetRequestId() uint32 { return m.RequestId }
|
||||
|
||||
// Get message
|
||||
type Get struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
ContainerId []byte
|
||||
EngineType EngineType
|
||||
}
|
||||
|
||||
func (m *Get) GetChainId() []byte { return m.ChainId }
|
||||
func (m *Get) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *Get) GetDeadline() uint64 { return m.Deadline }
|
||||
|
||||
// Put message
|
||||
type Put struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Container []byte
|
||||
EngineType EngineType
|
||||
}
|
||||
|
||||
func (m *Put) GetChainId() []byte { return m.ChainId }
|
||||
func (m *Put) GetRequestId() uint32 { return m.RequestId }
|
||||
|
||||
// PushQuery message
|
||||
type PushQuery struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
Container []byte
|
||||
EngineType EngineType
|
||||
RequestedHeight uint64
|
||||
}
|
||||
|
||||
func (m *PushQuery) GetChainId() []byte { return m.ChainId }
|
||||
func (m *PushQuery) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *PushQuery) GetDeadline() uint64 { return m.Deadline }
|
||||
|
||||
// PullQuery message
|
||||
type PullQuery struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
ContainerId []byte
|
||||
EngineType EngineType
|
||||
RequestedHeight uint64
|
||||
}
|
||||
|
||||
func (m *PullQuery) GetChainId() []byte { return m.ChainId }
|
||||
func (m *PullQuery) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *PullQuery) GetDeadline() uint64 { return m.Deadline }
|
||||
|
||||
// Chits message
|
||||
type Chits struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
PreferredId []byte
|
||||
PreferredIdAtHeight []byte
|
||||
AcceptedId []byte
|
||||
}
|
||||
|
||||
func (m *Chits) GetChainId() []byte { return m.ChainId }
|
||||
func (m *Chits) GetRequestId() uint32 { return m.RequestId }
|
||||
|
||||
// Request message (app-level)
|
||||
type Request struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Deadline uint64
|
||||
Request []byte
|
||||
}
|
||||
|
||||
func (m *Request) GetChainId() []byte { return m.ChainId }
|
||||
func (m *Request) GetRequestId() uint32 { return m.RequestId }
|
||||
func (m *Request) GetDeadline() uint64 { return m.Deadline }
|
||||
|
||||
// Response message (app-level)
|
||||
type Response struct {
|
||||
ChainId []byte
|
||||
RequestId uint32
|
||||
Response []byte
|
||||
}
|
||||
|
||||
func (m *Response) GetChainId() []byte { return m.ChainId }
|
||||
func (m *Response) GetRequestId() uint32 { return m.RequestId }
|
||||
|
||||
// Gossip message (app-level)
|
||||
type Gossip struct {
|
||||
ChainId []byte
|
||||
Gossip []byte
|
||||
}
|
||||
|
||||
func (m *Gossip) GetChainId() []byte { return m.ChainId }
|
||||
|
||||
// BFT message
|
||||
type BFT struct {
|
||||
ChainId []byte
|
||||
Message []byte
|
||||
}
|
||||
|
||||
func (m *BFT) GetChainId() []byte { return m.ChainId }
|
||||
+1150
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user