github.com/MetalBlockchain/metalgo@v1.11.9/network/test_network.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package network
     5  
     6  import (
     7  	"crypto"
     8  	"errors"
     9  	"math"
    10  	"net"
    11  	"net/netip"
    12  	"runtime"
    13  	"sync"
    14  
    15  	"github.com/prometheus/client_golang/prometheus"
    16  
    17  	"github.com/MetalBlockchain/metalgo/ids"
    18  	"github.com/MetalBlockchain/metalgo/message"
    19  	"github.com/MetalBlockchain/metalgo/network/dialer"
    20  	"github.com/MetalBlockchain/metalgo/network/peer"
    21  	"github.com/MetalBlockchain/metalgo/network/throttling"
    22  	"github.com/MetalBlockchain/metalgo/snow/networking/router"
    23  	"github.com/MetalBlockchain/metalgo/snow/networking/tracker"
    24  	"github.com/MetalBlockchain/metalgo/snow/uptime"
    25  	"github.com/MetalBlockchain/metalgo/snow/validators"
    26  	"github.com/MetalBlockchain/metalgo/staking"
    27  	"github.com/MetalBlockchain/metalgo/subnets"
    28  	"github.com/MetalBlockchain/metalgo/utils"
    29  	"github.com/MetalBlockchain/metalgo/utils/constants"
    30  	"github.com/MetalBlockchain/metalgo/utils/crypto/bls"
    31  	"github.com/MetalBlockchain/metalgo/utils/logging"
    32  	"github.com/MetalBlockchain/metalgo/utils/math/meter"
    33  	"github.com/MetalBlockchain/metalgo/utils/resource"
    34  	"github.com/MetalBlockchain/metalgo/utils/set"
    35  	"github.com/MetalBlockchain/metalgo/utils/units"
    36  )
    37  
    38  var (
    39  	errClosed = errors.New("closed")
    40  
    41  	_ net.Listener    = (*noopListener)(nil)
    42  	_ subnets.Allower = (*nodeIDConnector)(nil)
    43  )
    44  
    45  type noopListener struct {
    46  	once   sync.Once
    47  	closed chan struct{}
    48  }
    49  
    50  func newNoopListener() net.Listener {
    51  	return &noopListener{
    52  		closed: make(chan struct{}),
    53  	}
    54  }
    55  
    56  func (l *noopListener) Accept() (net.Conn, error) {
    57  	<-l.closed
    58  	return nil, errClosed
    59  }
    60  
    61  func (l *noopListener) Close() error {
    62  	l.once.Do(func() {
    63  		close(l.closed)
    64  	})
    65  	return nil
    66  }
    67  
    68  func (*noopListener) Addr() net.Addr {
    69  	return &net.TCPAddr{
    70  		IP:   net.IPv4zero,
    71  		Port: 1,
    72  	}
    73  }
    74  
    75  func NewTestNetwork(
    76  	log logging.Logger,
    77  	networkID uint32,
    78  	currentValidators validators.Manager,
    79  	trackedSubnets set.Set[ids.ID],
    80  	router router.ExternalHandler,
    81  ) (Network, error) {
    82  	metrics := prometheus.NewRegistry()
    83  	msgCreator, err := message.NewCreator(
    84  		logging.NoLog{},
    85  		metrics,
    86  		constants.DefaultNetworkCompressionType,
    87  		constants.DefaultNetworkMaximumInboundTimeout,
    88  	)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	tlsCert, err := staking.NewTLSCert()
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  
    98  	blsKey, err := bls.NewSecretKey()
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	// TODO actually monitor usage
   104  	// TestNetwork doesn't use disk so we don't need to track it, but we should
   105  	// still have guardrails around cpu/memory usage.
   106  	resourceTracker, err := tracker.NewResourceTracker(
   107  		metrics,
   108  		resource.NoUsage,
   109  		&meter.ContinuousFactory{},
   110  		constants.DefaultHealthCheckAveragerHalflife,
   111  	)
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  
   116  	return NewNetwork(
   117  		&Config{
   118  			HealthConfig: HealthConfig{
   119  				Enabled:                      true,
   120  				MinConnectedPeers:            constants.DefaultNetworkHealthMinPeers,
   121  				MaxTimeSinceMsgReceived:      constants.DefaultNetworkHealthMaxTimeSinceMsgReceived,
   122  				MaxTimeSinceMsgSent:          constants.DefaultNetworkHealthMaxTimeSinceMsgSent,
   123  				MaxPortionSendQueueBytesFull: constants.DefaultNetworkHealthMaxPortionSendQueueFill,
   124  				MaxSendFailRate:              constants.DefaultNetworkHealthMaxSendFailRate,
   125  				SendFailRateHalflife:         constants.DefaultHealthCheckAveragerHalflife,
   126  			},
   127  			PeerListGossipConfig: PeerListGossipConfig{
   128  				PeerListNumValidatorIPs: constants.DefaultNetworkPeerListNumValidatorIPs,
   129  				PeerListPullGossipFreq:  constants.DefaultNetworkPeerListPullGossipFreq,
   130  				PeerListBloomResetFreq:  constants.DefaultNetworkPeerListBloomResetFreq,
   131  			},
   132  			TimeoutConfig: TimeoutConfig{
   133  				PingPongTimeout:      constants.DefaultPingPongTimeout,
   134  				ReadHandshakeTimeout: constants.DefaultNetworkReadHandshakeTimeout,
   135  			},
   136  			DelayConfig: DelayConfig{
   137  				InitialReconnectDelay: constants.DefaultNetworkInitialReconnectDelay,
   138  				MaxReconnectDelay:     constants.DefaultNetworkMaxReconnectDelay,
   139  			},
   140  			ThrottlerConfig: ThrottlerConfig{
   141  				InboundConnUpgradeThrottlerConfig: throttling.InboundConnUpgradeThrottlerConfig{
   142  					UpgradeCooldown:        constants.DefaultInboundConnUpgradeThrottlerCooldown,
   143  					MaxRecentConnsUpgraded: int(math.Ceil(constants.DefaultInboundThrottlerMaxConnsPerSec * constants.DefaultInboundConnUpgradeThrottlerCooldown.Seconds())),
   144  				},
   145  				InboundMsgThrottlerConfig: throttling.InboundMsgThrottlerConfig{
   146  					MsgByteThrottlerConfig: throttling.MsgByteThrottlerConfig{
   147  						VdrAllocSize:        constants.DefaultInboundThrottlerVdrAllocSize,
   148  						AtLargeAllocSize:    constants.DefaultInboundThrottlerAtLargeAllocSize,
   149  						NodeMaxAtLargeBytes: constants.DefaultInboundThrottlerNodeMaxAtLargeBytes,
   150  					},
   151  					BandwidthThrottlerConfig: throttling.BandwidthThrottlerConfig{
   152  						RefillRate:   constants.DefaultInboundThrottlerBandwidthRefillRate,
   153  						MaxBurstSize: constants.DefaultInboundThrottlerBandwidthMaxBurstSize,
   154  					},
   155  					CPUThrottlerConfig: throttling.SystemThrottlerConfig{
   156  						MaxRecheckDelay: constants.DefaultInboundThrottlerCPUMaxRecheckDelay,
   157  					},
   158  					DiskThrottlerConfig: throttling.SystemThrottlerConfig{
   159  						MaxRecheckDelay: constants.DefaultInboundThrottlerDiskMaxRecheckDelay,
   160  					},
   161  					MaxProcessingMsgsPerNode: constants.DefaultInboundThrottlerMaxProcessingMsgsPerNode,
   162  				},
   163  				OutboundMsgThrottlerConfig: throttling.MsgByteThrottlerConfig{
   164  					VdrAllocSize:        constants.DefaultOutboundThrottlerVdrAllocSize,
   165  					AtLargeAllocSize:    constants.DefaultOutboundThrottlerAtLargeAllocSize,
   166  					NodeMaxAtLargeBytes: constants.DefaultOutboundThrottlerNodeMaxAtLargeBytes,
   167  				},
   168  				MaxInboundConnsPerSec: constants.DefaultInboundThrottlerMaxConnsPerSec,
   169  			},
   170  			ProxyEnabled:           constants.DefaultNetworkTCPProxyEnabled,
   171  			ProxyReadHeaderTimeout: constants.DefaultNetworkTCPProxyReadTimeout,
   172  			DialerConfig: dialer.Config{
   173  				ThrottleRps:       constants.DefaultOutboundConnectionThrottlingRps,
   174  				ConnectionTimeout: constants.DefaultOutboundConnectionTimeout,
   175  			},
   176  			TLSConfig: peer.TLSConfig(*tlsCert, nil),
   177  			MyIPPort: utils.NewAtomic(netip.AddrPortFrom(
   178  				netip.IPv4Unspecified(),
   179  				1,
   180  			)),
   181  			NetworkID:                    networkID,
   182  			MaxClockDifference:           constants.DefaultNetworkMaxClockDifference,
   183  			PingFrequency:                constants.DefaultPingFrequency,
   184  			AllowPrivateIPs:              !constants.ProductionNetworkIDs.Contains(networkID),
   185  			CompressionType:              constants.DefaultNetworkCompressionType,
   186  			TLSKey:                       tlsCert.PrivateKey.(crypto.Signer),
   187  			BLSKey:                       blsKey,
   188  			TrackedSubnets:               trackedSubnets,
   189  			Beacons:                      validators.NewManager(),
   190  			Validators:                   currentValidators,
   191  			UptimeCalculator:             uptime.NoOpCalculator,
   192  			UptimeMetricFreq:             constants.DefaultUptimeMetricFreq,
   193  			RequireValidatorToConnect:    constants.DefaultNetworkRequireValidatorToConnect,
   194  			MaximumInboundMessageTimeout: constants.DefaultNetworkMaximumInboundTimeout,
   195  			PeerReadBufferSize:           constants.DefaultNetworkPeerReadBufferSize,
   196  			PeerWriteBufferSize:          constants.DefaultNetworkPeerWriteBufferSize,
   197  			ResourceTracker:              resourceTracker,
   198  			CPUTargeter: tracker.NewTargeter(
   199  				logging.NoLog{},
   200  				&tracker.TargeterConfig{
   201  					VdrAlloc:           float64(runtime.NumCPU()),
   202  					MaxNonVdrUsage:     .8 * float64(runtime.NumCPU()),
   203  					MaxNonVdrNodeUsage: float64(runtime.NumCPU()) / 8,
   204  				},
   205  				currentValidators,
   206  				resourceTracker.CPUTracker(),
   207  			),
   208  			DiskTargeter: tracker.NewTargeter(
   209  				logging.NoLog{},
   210  				&tracker.TargeterConfig{
   211  					VdrAlloc:           1000 * units.GiB,
   212  					MaxNonVdrUsage:     1000 * units.GiB,
   213  					MaxNonVdrNodeUsage: 1000 * units.GiB,
   214  				},
   215  				currentValidators,
   216  				resourceTracker.DiskTracker(),
   217  			),
   218  		},
   219  		msgCreator,
   220  		metrics,
   221  		log,
   222  		newNoopListener(),
   223  		dialer.NewDialer(
   224  			constants.NetworkType,
   225  			dialer.Config{
   226  				ThrottleRps:       constants.DefaultOutboundConnectionThrottlingRps,
   227  				ConnectionTimeout: constants.DefaultOutboundConnectionTimeout,
   228  			},
   229  			log,
   230  		),
   231  		router,
   232  	)
   233  }
   234  
   235  type nodeIDConnector struct {
   236  	nodeID ids.NodeID
   237  }
   238  
   239  func newNodeIDConnector(nodeID ids.NodeID) *nodeIDConnector {
   240  	return &nodeIDConnector{nodeID: nodeID}
   241  }
   242  
   243  func (f *nodeIDConnector) IsAllowed(nodeID ids.NodeID, _ bool) bool {
   244  	return nodeID == f.nodeID
   245  }