@@ -35,6 +35,8 @@ import (
3535 "google.golang.org/grpc"
3636 "google.golang.org/grpc/credentials/insecure"
3737
38+ errorsmod "cosmossdk.io/errors"
39+ "cosmossdk.io/log"
3840 pruningtypes "cosmossdk.io/store/pruning/types"
3941
4042 "github.com/cosmos/cosmos-sdk/client"
@@ -96,11 +98,12 @@ const (
9698
9799 // gRPC-related flags
98100
99- flagGRPCOnly = "grpc-only"
100- flagGRPCEnable = "grpc.enable"
101- flagGRPCAddress = "grpc.address"
102- flagGRPCWebEnable = "grpc-web.enable"
103- flagGRPCSkipCheckHeader = "grpc.skip-check-header"
101+ flagGRPCOnly = "grpc-only"
102+ flagGRPCEnable = "grpc.enable"
103+ flagGRPCAddress = "grpc.address"
104+ flagGRPCWebEnable = "grpc-web.enable"
105+ flagGRPCSkipCheckHeader = "grpc.skip-check-header"
106+ flagBackupGRPCBlockAddressBlockRange = "grpc.backup-grpc-address-block-range"
104107
105108 // mempool flags
106109
@@ -451,6 +454,53 @@ func setupTraceWriter(svrCtx *Context) (traceWriter io.WriteCloser, cleanup func
451454 return traceWriter , cleanup , nil
452455}
453456
457+ func parseGrpcAddress (address string ) (string , error ) {
458+ host , port , err := net .SplitHostPort (address )
459+ if err != nil {
460+ return "" , errorsmod .Wrapf (err , "invalid grpc address %s" , address )
461+ }
462+ return fmt .Sprintf ("%s:%s" , host , port ), nil
463+ }
464+
465+ // SetupBackupGRPCConnections creates backup gRPC connections based on the configuration
466+ // and returns a client context with the GRPCConnProvider configured.
467+ func SetupBackupGRPCConnections (
468+ clientCtx client.Context ,
469+ grpcClient * grpc.ClientConn ,
470+ backupAddresses map [serverconfig.BlockRange ]string ,
471+ maxRecvMsgSize , maxSendMsgSize int ,
472+ logger log.Logger ,
473+ ) (client.Context , error ) {
474+ if len (backupAddresses ) == 0 {
475+ return clientCtx , nil
476+ }
477+
478+ backupConns := make (serverconfig.BackupGRPCConnections )
479+ for blockRange , address := range backupAddresses {
480+ grpcAddr , err := parseGrpcAddress (address )
481+ if err != nil {
482+ return clientCtx , err
483+ }
484+ conn , err := grpc .NewClient (
485+ grpcAddr ,
486+ grpc .WithTransportCredentials (insecure .NewCredentials ()),
487+ grpc .WithDefaultCallOptions (
488+ grpc .ForceCodec (codec .NewProtoCodec (clientCtx .InterfaceRegistry ).GRPCCodec ()),
489+ grpc .MaxCallRecvMsgSize (maxRecvMsgSize ),
490+ grpc .MaxCallSendMsgSize (maxSendMsgSize ),
491+ ),
492+ )
493+ if err != nil {
494+ return clientCtx , err
495+ }
496+ backupConns [blockRange ] = conn
497+ }
498+
499+ clientCtx = clientCtx .WithGRPCConnProvider (client .NewGRPCConnProvider (grpcClient , backupConns ))
500+ logger .Info ("backup gRPC connections configured" , "count" , len (backupConns ))
501+ return clientCtx , nil
502+ }
503+
454504func startGrpcServer (
455505 ctx context.Context ,
456506 g * errgroup.Group ,
@@ -479,7 +529,7 @@ func startGrpcServer(
479529 }
480530
481531 // if gRPC is enabled, configure gRPC client for gRPC gateway
482- grpcClient , err := grpc .Dial ( //nolint: staticcheck // ignore this line for this linter
532+ grpcClient , err := grpc .NewClient (
483533 config .Address ,
484534 grpc .WithTransportCredentials (insecure .NewCredentials ()),
485535 grpc .WithDefaultCallOptions (
@@ -495,6 +545,19 @@ func startGrpcServer(
495545 clientCtx = clientCtx .WithGRPCClient (grpcClient )
496546 svrCtx .Logger .Debug ("gRPC client assigned to client context" , "target" , config .Address )
497547
548+ // Setup backup gRPC connections if configured
549+ clientCtx , err = SetupBackupGRPCConnections (
550+ clientCtx ,
551+ grpcClient ,
552+ config .BackupGRPCBlockAddressBlockRange ,
553+ maxRecvMsgSize ,
554+ maxSendMsgSize ,
555+ svrCtx .Logger ,
556+ )
557+ if err != nil {
558+ return nil , clientCtx , err
559+ }
560+
498561 grpcSrv , err := servergrpc .NewGRPCServer (clientCtx , app , config )
499562 if err != nil {
500563 return nil , clientCtx , err
@@ -994,6 +1057,7 @@ func addStartNodeFlags(cmd *cobra.Command, opts StartCmdOptions) {
9941057 cmd .Flags ().Bool (flagGRPCEnable , true , "Define if the gRPC server should be enabled" )
9951058 cmd .Flags ().String (flagGRPCAddress , serverconfig .DefaultGRPCAddress , "the gRPC server address to listen on" )
9961059 cmd .Flags ().Bool (flagGRPCWebEnable , true , "Define if the gRPC-Web server should be enabled. (Note: gRPC must also be enabled)" )
1060+ cmd .Flags ().String (flagBackupGRPCBlockAddressBlockRange , "" , "Define if backup grpc and block range is available" )
9971061 cmd .Flags ().Uint64 (FlagStateSyncSnapshotInterval , 0 , "State sync snapshot interval" )
9981062 cmd .Flags ().Uint32 (FlagStateSyncSnapshotKeepRecent , 2 , "State sync snapshot to keep" )
9991063 cmd .Flags ().Bool (FlagDisableIAVLFastNode , false , "Disable fast node for IAVL tree" )
0 commit comments