Skip to content
Open
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions vms/evm/gossip/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package gossip

import (
"context"
"fmt"
"time"

"github.com/prometheus/client_golang/prometheus"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/network/p2p"
"github.com/ava-labs/avalanchego/network/p2p/gossip"
"github.com/ava-labs/avalanchego/snow/engine/common"
"github.com/ava-labs/avalanchego/utils/logging"
)

var _ p2p.Handler = (*txGossipHandler)(nil)

type txGossipHandler struct {
appGossipHandler p2p.Handler
appRequestHandler p2p.Handler
}

func NewTxGossipHandler[T gossip.Gossipable](
log logging.Logger,
marshaller gossip.Marshaller[T],
mempool gossip.Set[T],
metrics gossip.Metrics,
maxMessageSize int,
throttlingPeriod time.Duration,
requestsPerPeer float64,
validators p2p.ValidatorSet,
registerer prometheus.Registerer,
namespace string,
) (*txGossipHandler, error) {
// push gossip messages can be handled from any peer
handler := gossip.NewHandler(
log,
marshaller,
mempool,
metrics,
maxMessageSize,
)

throttledHandler, err := p2p.NewDynamicThrottlerHandler(
log,
handler,
validators,
throttlingPeriod,
requestsPerPeer,
registerer,
namespace,
)
if err != nil {
return nil, fmt.Errorf("failed to initialize throttler handler: %w", err)
}

// pull gossip requests are filtered by validators and are throttled
// to prevent spamming
validatorHandler := p2p.NewValidatorHandler(
throttledHandler,
validators,
log,
)

return &txGossipHandler{
appGossipHandler: handler,
appRequestHandler: validatorHandler,
}, nil
}

func (t *txGossipHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) {
t.appGossipHandler.AppGossip(ctx, nodeID, gossipBytes)
}

func (t *txGossipHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, *common.AppError) {
return t.appRequestHandler.AppRequest(ctx, nodeID, deadline, requestBytes)
}