From 400b2d0f48fea322f7a93028481de87f200c7f89 Mon Sep 17 00:00:00 2001 From: Mohamed Awnallah Date: Sun, 31 Mar 2024 07:31:20 +0200 Subject: [PATCH] chainreg: add `checkOutboundPeers` function In this commit we add `checkOutboundPeers` function to the `cc.HealthCheck` function. --- chainreg/chainregistry.go | 57 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/chainreg/chainregistry.go b/chainreg/chainregistry.go index 02da263912..7c648ac3ba 100644 --- a/chainreg/chainregistry.go +++ b/chainreg/chainregistry.go @@ -122,6 +122,11 @@ const ( // DefaultBitcoinStaticMinRelayFeeRate is the min relay fee used for // static estimators. DefaultBitcoinStaticMinRelayFeeRate = chainfee.FeePerKwFloor + + // DefaultMinOutboundPeers is the min number of connected + // outbound peers the chain backend should have to maintains a + // healthy connection to the network. + DefaultMinOutboundPeers = 6 ) // PartialChainControl contains all the primary interfaces of the chain control @@ -504,7 +509,14 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) { cc.HealthCheck = func() error { _, err := chainConn.RawRequest(cmd, nil) - return err + if err != nil { + return err + } + + // Make sure the bitcoind chain backend maintains a + // healthy connection to the network by checking the + // number of outbound peers. + return checkOutboundPeers(cfg, chainConn) } case "btcd": @@ -613,7 +625,14 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) { // Use a query for our best block as a health check. cc.HealthCheck = func() error { _, _, err := cc.ChainSource.GetBestBlock() - return err + if err != nil { + return err + } + + // Make sure the btcd chain backend maintains a + // healthy connection to the network by checking the + // number of outbound peers. + return checkOutboundPeers(cfg, chainRPC.Client) } // If we're not in simnet or regtest mode, then we'll attempt @@ -840,3 +859,37 @@ var ( }, } ) + +// checkOutboundPeers checks the number of outbound peers connected to the +// provided RPC client. If the number of outbound peers is below 6, a warning +// is logged. This function is intended to ensure that the chain backend +// maintains a healthy connection to the network. +func checkOutboundPeers(cfg *Config, client *rpcclient.Client) error { + // On local test networks we usually don't have multiple + // chain backend peers, so we can skip that test. + if cfg.Bitcoin.SimNet || cfg.Bitcoin.RegTest { + return nil + } + + peers, err := client.GetPeerInfo() + if err != nil { + return err + } + + var outboundPeers int + for _, peer := range peers { + if !peer.Inbound { + outboundPeers++ + } + } + + if outboundPeers < DefaultMinOutboundPeers { + log.Warnf("The chain backend has an insufficient number "+ + "of connected outbound peers (%d connected, expected "+ + "minimum is %d) which can be a security issue. "+ + "Connect to more trusted nodes manually if necessary.", + outboundPeers, DefaultMinOutboundPeers) + } + + return nil +}