diff --git a/bor/client/grpc/client.go b/bor/client/grpc/client.go new file mode 100644 index 000000000..e8da2221e --- /dev/null +++ b/bor/client/grpc/client.go @@ -0,0 +1,59 @@ +package grpc + +import ( + "strings" + "time" + + "github.com/ethereum/go-ethereum/log" + grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry" + + proto "github.com/maticnetwork/polyproto/bor" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" +) + +type BorGRPCClient struct { + conn *grpc.ClientConn + client proto.BorApiClient +} + +func NewBorGRPCClient(address string) *BorGRPCClient { + address = removePrefix(address) + + opts := []grpc_retry.CallOption{ + grpc_retry.WithMax(5), + grpc_retry.WithBackoff(grpc_retry.BackoffLinear(1 * time.Second)), + grpc_retry.WithCodes(codes.Internal, codes.Unavailable, codes.Aborted, codes.NotFound), + } + + conn, err := grpc.NewClient(address, + grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(opts...)), + grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(opts...)), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + log.Crit("Failed to connect to Bor gRPC", "error", err) + } + + log.Info("Connected to Bor gRPC server", "address", address) + + return &BorGRPCClient{ + conn: conn, + client: proto.NewBorApiClient(conn), + } +} + +func (h *BorGRPCClient) Close() { + log.Debug("Shutdown detected, Closing Bor gRPC client") + h.conn.Close() +} + +// removePrefix removes the http:// or https:// prefix from the address, if present. +func removePrefix(address string) string { + if strings.HasPrefix(address, "http://") || strings.HasPrefix(address, "https://") { + return address[strings.Index(address, "//")+2:] + } + return address +} diff --git a/bor/client/grpc/query.go b/bor/client/grpc/query.go new file mode 100644 index 000000000..36e07663c --- /dev/null +++ b/bor/client/grpc/query.go @@ -0,0 +1,155 @@ +package grpc + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/common" + ethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + + proto "github.com/maticnetwork/polyproto/bor" + protoutil "github.com/maticnetwork/polyproto/utils" +) + +func (h *BorGRPCClient) GetRootHash(ctx context.Context, startBlock uint64, endBlock uint64) (string, error) { + + req := &proto.GetRootHashRequest{ + StartBlockNumber: startBlock, + EndBlockNumber: endBlock, + } + + log.Info("Fetching bor root hash") + + res, err := h.client.GetRootHash(ctx, req) + if err != nil { + return "", err + } + + log.Info("Fetched bor root hash") + + return res.RootHash, nil +} + +func (h *BorGRPCClient) GetVoteOnHash(ctx context.Context, startBlock uint64, endBlock uint64, rootHash string, milestoneId string) (bool, error) { + + req := &proto.GetVoteOnHashRequest{ + StartBlockNumber: startBlock, + EndBlockNumber: endBlock, + Hash: rootHash, + MilestoneId: milestoneId, + } + + log.Info("Fetching vote on hash") + + res, err := h.client.GetVoteOnHash(ctx, req) + if err != nil { + return false, err + } + + log.Info("Fetched vote on hash") + + return res.Response, nil +} + +func (h *BorGRPCClient) HeaderByNumber(ctx context.Context, blockID uint64) (*ethTypes.Header, error) { + + req := &proto.GetHeaderByNumberRequest{ + Number: blockID, + } + + log.Info("Fetching header by number") + + res, err := h.client.HeaderByNumber(ctx, req) + if err != nil { + return ðTypes.Header{}, err + } + + log.Info("Fetched header by number") + + resp := ðTypes.Header{ + Number: big.NewInt(int64(res.Header.Number)), + ParentHash: protoutil.ConvertH256ToHash(res.Header.ParentHash), + Time: res.Header.Time, + } + + return resp, nil +} + +func (h *BorGRPCClient) BlockByNumber(ctx context.Context, blockID uint64) (*ethTypes.Block, error) { + + req := &proto.GetBlockByNumberRequest{ + Number: blockID, + } + + log.Info("Fetching block by number") + + res, err := h.client.BlockByNumber(ctx, req) + if err != nil { + return ðTypes.Block{}, err + } + + log.Info("Fetched block by number") + + header := ethTypes.Header{ + Number: big.NewInt(int64(res.Block.Header.Number)), + ParentHash: protoutil.ConvertH256ToHash(res.Block.Header.ParentHash), + Time: res.Block.Header.Time, + } + return ethTypes.NewBlock(&header, nil, nil, nil, nil), nil +} + +func (h *BorGRPCClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*ethTypes.Receipt, error) { + + req := &proto.ReceiptRequest{ + Hash: protoutil.ConvertHashToH256(txHash), + } + + log.Info("Fetching transaction receipt") + + res, err := h.client.TransactionReceipt(ctx, req) + if err != nil { + return ðTypes.Receipt{}, err + } + + log.Info("Fetched transaction receipt") + + return receiptResponseToTypesReceipt(res.Receipt), nil +} + +func (h *BorGRPCClient) BorBlockReceipt(ctx context.Context, txHash common.Hash) (*ethTypes.Receipt, error) { + + req := &proto.ReceiptRequest{ + Hash: protoutil.ConvertHashToH256(txHash), + } + + log.Info("Fetching bor block receipt") + + res, err := h.client.BorBlockReceipt(ctx, req) + if err != nil { + return ðTypes.Receipt{}, err + } + + log.Info("Fetched bor block receipt") + + return receiptResponseToTypesReceipt(res.Receipt), nil +} + +func receiptResponseToTypesReceipt(receipt *proto.Receipt) *ethTypes.Receipt { + // Bloom and Logs have been intentionally left out as they are not used in the current implementation + return ðTypes.Receipt{ + Type: uint8(receipt.Type), + PostState: receipt.PostState, + Status: receipt.Status, + CumulativeGasUsed: receipt.CumulativeGasUsed, + TxHash: protoutil.ConvertH256ToHash(receipt.TxHash), + ContractAddress: protoutil.ConvertH160toAddress(receipt.ContractAddress), + GasUsed: receipt.GasUsed, + EffectiveGasPrice: big.NewInt(receipt.EffectiveGasPrice), + BlobGasUsed: receipt.BlobGasUsed, + BlobGasPrice: big.NewInt(receipt.BlobGasPrice), + BlockHash: protoutil.ConvertH256ToHash(receipt.BlockHash), + BlockNumber: big.NewInt(receipt.BlockNumber), + TransactionIndex: uint(receipt.TransactionIndex), + } +} diff --git a/bridge/setu/broadcaster/broadcaster_test.go b/bridge/setu/broadcaster/broadcaster_test.go index 27ab643b5..7870a5668 100644 --- a/bridge/setu/broadcaster/broadcaster_test.go +++ b/bridge/setu/broadcaster/broadcaster_test.go @@ -114,7 +114,7 @@ var ( } ) -// Parallel test - to check BroadcastToHeimdall synchronisation +//nolint:tparallel func TestBroadcastToHeimdall(t *testing.T) { t.Parallel() diff --git a/bridge/setu/processor/milestone.go b/bridge/setu/processor/milestone.go index f01298846..66c8fa5e8 100644 --- a/bridge/setu/processor/milestone.go +++ b/bridge/setu/processor/milestone.go @@ -105,7 +105,7 @@ func (mp *MilestoneProcessor) checkAndPropose(milestoneLength uint64) (err error } if result == nil { - return fmt.Errorf("Got nil result while fetching milestone count") + return errors.New("got nil result while fetching milestone count") } var start = helper.GetMilestoneBorBlockHeight() @@ -118,7 +118,7 @@ func (mp *MilestoneProcessor) checkAndPropose(milestoneLength uint64) (err error } if latestMilestone == nil { - return errors.New("Got nil result while fetching latest milestone") + return errors.New("got nil result while fetching latest milestone") } //start block number should be continuous to the end block of lasted stored milestone @@ -160,7 +160,7 @@ func (mp *MilestoneProcessor) createAndSendMilestoneToHeimdall(milestoneContext //fetch the endBlock+1 number instead of endBlock so that we can directly get the hash of endBlock using parent hash block, err = mp.contractConnector.GetMaticChainBlock(big.NewInt(int64(endNum + 1))) if err != nil { - return fmt.Errorf("Error while fetching %d block %w", endNum+1, err) + return fmt.Errorf("error while fetching block %d: %w", endNum+1, err) } endHash := block.ParentHash diff --git a/cmd/heimdalld/service/service.go b/cmd/heimdalld/service/service.go index 7e01297a7..be1932dbc 100644 --- a/cmd/heimdalld/service/service.go +++ b/cmd/heimdalld/service/service.go @@ -22,6 +22,7 @@ import ( "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" + ethCommon "github.com/ethereum/go-ethereum/common" jsoniter "github.com/json-iterator/go" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -49,9 +50,6 @@ import ( sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "golang.org/x/sync/errgroup" - "google.golang.org/grpc" - - ethCommon "github.com/ethereum/go-ethereum/common" "github.com/maticnetwork/heimdall/app" authTypes "github.com/maticnetwork/heimdall/auth/types" @@ -365,7 +363,7 @@ func startOpenTracing(cmd *cobra.Command) (*sdktrace.TracerProvider, *context.Co ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint(openCollectorEndpoint), - otlptracegrpc.WithDialOption(grpc.WithBlock()), + otlptracegrpc.WithDialOption(), ) traceExporterReady <- traceExporter }() diff --git a/go.mod b/go.mod index 8bb28b171..c976c52f6 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,10 @@ require ( github.com/golang/mock v1.6.0 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/hashicorp/golang-lru v1.0.2 github.com/json-iterator/go v1.1.12 - github.com/maticnetwork/polyproto v0.0.3-0.20230216113155-340ea926ca53 + github.com/maticnetwork/polyproto v0.0.3 github.com/pborman/uuid v1.2.1 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.0 diff --git a/go.sum b/go.sum index 8c5059c03..5d48562bb 100644 --- a/go.sum +++ b/go.sum @@ -1995,6 +1995,7 @@ github.com/gorilla/websocket v1.5.2 h1:qoW6V1GT3aZxybsbC6oLnailWnB+qTMVwMreOso9X github.com/gorilla/websocket v1.5.2/go.mod h1:0n9H61RBAcf5/38py2MCYbxzPIY9rOkpvvMT24Rqs30= github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -2223,8 +2224,9 @@ github.com/maticnetwork/cosmos-sdk v0.38.4/go.mod h1:NbuVdUoqlRF6RrFJp27hpbqSoRB github.com/maticnetwork/crand v1.0.2 h1:Af0tAivC8zrxXDpGWNWVT/0s1fOz8w0eRbahZgURS8I= github.com/maticnetwork/crand v1.0.2/go.mod h1:/NRNL3bj2eYdqpWmoIP5puxndTpi0XRxpj5ZKxfHjyg= github.com/maticnetwork/heimdall v1.0.7/go.mod h1:+ANI5+VV28ahwfdl7oMzrcNwaTEs1Fn6z39BqBGcvaA= -github.com/maticnetwork/polyproto v0.0.3-0.20230216113155-340ea926ca53 h1:PjYV+lghs106JKkrYgOnrsfDLoTc11BxZd4rUa4Rus4= github.com/maticnetwork/polyproto v0.0.3-0.20230216113155-340ea926ca53/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o= +github.com/maticnetwork/polyproto v0.0.3 h1:a69rIp97fcl3ABY4LlVX9B2t1qhLa0Jhny3HNOzReBU= +github.com/maticnetwork/polyproto v0.0.3/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o= github.com/maticnetwork/tendermint v0.33.2 h1:R9M7jgAmON8K/LbzMvtWPDhtPkNcqzkUUHp1ict/h3s= github.com/maticnetwork/tendermint v0.33.2/go.mod h1:D2fcnxGk6bje+LoPwImuKSSYLiK7/G06IynGNDSEcJk= github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= diff --git a/helper/call.go b/helper/call.go index 75424a496..556291d41 100644 --- a/helper/call.go +++ b/helper/call.go @@ -16,6 +16,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" lru "github.com/hashicorp/golang-lru" + "github.com/maticnetwork/heimdall/bor/client/grpc" "github.com/maticnetwork/heimdall/contracts/erc20" "github.com/maticnetwork/heimdall/contracts/rootchain" "github.com/maticnetwork/heimdall/contracts/slashmanager" @@ -100,11 +101,18 @@ type IContractCaller interface { // ContractCaller contract caller type ContractCaller struct { - MainChainClient *ethclient.Client - MainChainRPC *rpc.Client - MainChainTimeout time.Duration - MaticChainClient *ethclient.Client - MaticChainRPC *rpc.Client + MainChainClient *ethclient.Client + MainChainRPC *rpc.Client + MainChainTimeout time.Duration + + // MaticGrpcFlag is a flag to check if the client is grpc or not + MaticGrpcFlag bool + + MaticChainClient *ethclient.Client + MaticChainRPC *rpc.Client + + MaticGrpcClient *grpc.BorGRPCClient + MaticChainTimeout time.Duration RootChainABI abi.ABI @@ -141,6 +149,8 @@ func NewContractCaller() (contractCallerObj ContractCaller, err error) { contractCallerObj.MainChainRPC = GetMainChainRPCClient() contractCallerObj.MaticChainRPC = GetMaticRPCClient() contractCallerObj.ReceiptCache, err = lru.New(1000) + contractCallerObj.MaticGrpcFlag = config.BorGRPCFlag + contractCallerObj.MaticGrpcClient = GetMaticGRPCClient() if err != nil { return contractCallerObj, err @@ -300,7 +310,15 @@ func (c *ContractCaller) GetRootHash(start uint64, end uint64, checkpointLength ctx, cancel := context.WithTimeout(context.Background(), c.MaticChainTimeout) defer cancel() - rootHash, err := c.MaticChainClient.GetRootHash(ctx, start, end) + var rootHash string + var err error + + // Both MainChainClient and MaticChainClient cannot be nil, check it while initializing + if c.MaticGrpcFlag { + rootHash, err = c.MaticGrpcClient.GetRootHash(ctx, start, end) + } else { + rootHash, err = c.MaticChainClient.GetRootHash(ctx, start, end) + } if err != nil { Logger.Error("Could not fetch rootHash from matic chain", "error", err) @@ -319,7 +337,15 @@ func (c *ContractCaller) GetVoteOnHash(start uint64, end uint64, milestoneLength ctx, cancel := context.WithTimeout(context.Background(), c.MaticChainTimeout) defer cancel() - vote, err := c.MaticChainClient.GetVoteOnHash(ctx, start, end, hash, milestoneID) + var vote bool + var err error + + if c.MaticGrpcFlag { + vote, err = c.MaticGrpcClient.GetVoteOnHash(ctx, start, end, hash, milestoneID) + } else { + vote, err = c.MaticChainClient.GetVoteOnHash(ctx, start, end, hash, milestoneID) + } + if err != nil { return false, errors.New(fmt.Sprint("Error in fetching vote from matic chain", "err", err)) } @@ -436,7 +462,17 @@ func (c *ContractCaller) GetMaticChainBlock(blockNum *big.Int) (header *ethTypes ctx, cancel := context.WithTimeout(context.Background(), c.MaticChainTimeout) defer cancel() - latestBlock, err := c.MaticChainClient.HeaderByNumber(ctx, blockNum) + var latestBlock *ethTypes.Header + + if c.MaticGrpcFlag && blockNum != nil { + if blockNum.Sign() < 0 { + blockNum = new(big.Int).Abs(blockNum) + } + latestBlock, err = c.MaticGrpcClient.HeaderByNumber(ctx, blockNum.Uint64()) + } else { + latestBlock, err = c.MaticChainClient.HeaderByNumber(ctx, blockNum) + } + if err != nil { Logger.Error("Unable to connect to matic chain", "error", err) return @@ -846,7 +882,15 @@ func (c *ContractCaller) CheckIfBlocksExist(end uint64) bool { // GetBlockByNumber returns blocks by number from child chain (bor) func (c *ContractCaller) GetBlockByNumber(ctx context.Context, blockNumber uint64) *ethTypes.Block { - block, err := c.MaticChainClient.BlockByNumber(ctx, big.NewInt(int64(blockNumber))) + var block *ethTypes.Block + var err error + + if c.MaticGrpcFlag && big.NewInt(int64(blockNumber)) != nil { + block, err = c.MaticGrpcClient.BlockByNumber(ctx, blockNumber) + } else { + block, err = c.MaticChainClient.BlockByNumber(ctx, big.NewInt(int64(blockNumber))) + } + if err != nil { Logger.Error("Unable to fetch block by number from child chain", "block", block, "err", err) return nil @@ -864,7 +908,7 @@ func (c *ContractCaller) GetMainTxReceipt(txHash common.Hash) (*ethTypes.Receipt ctx, cancel := context.WithTimeout(context.Background(), c.MainChainTimeout) defer cancel() - return c.getTxReceipt(ctx, c.MainChainClient, txHash) + return c.getTxReceipt(ctx, c.MainChainClient, nil, txHash) } // GetMaticTxReceipt returns matic tx receipt @@ -872,10 +916,16 @@ func (c *ContractCaller) GetMaticTxReceipt(txHash common.Hash) (*ethTypes.Receip ctx, cancel := context.WithTimeout(context.Background(), c.MaticChainTimeout) defer cancel() - return c.getTxReceipt(ctx, c.MaticChainClient, txHash) + if c.MaticGrpcFlag { + return c.getTxReceipt(ctx, nil, c.MaticGrpcClient, txHash) + } + return c.getTxReceipt(ctx, c.MaticChainClient, nil, txHash) } -func (c *ContractCaller) getTxReceipt(ctx context.Context, client *ethclient.Client, txHash common.Hash) (*ethTypes.Receipt, error) { +func (c *ContractCaller) getTxReceipt(ctx context.Context, client *ethclient.Client, grpcClient *grpc.BorGRPCClient, txHash common.Hash) (*ethTypes.Receipt, error) { + if grpcClient != nil { + return grpcClient.TransactionReceipt(ctx, txHash) + } return client.TransactionReceipt(ctx, txHash) } diff --git a/helper/config.go b/helper/config.go index 994c2a20e..e0d4ee9f9 100644 --- a/helper/config.go +++ b/helper/config.go @@ -17,15 +17,15 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/tendermint/go-amino" + cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto/secp256k1" logger "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/privval" + tmTypes "github.com/tendermint/tendermint/types" + borgrpc "github.com/maticnetwork/heimdall/bor/client/grpc" "github.com/maticnetwork/heimdall/file" hmTypes "github.com/maticnetwork/heimdall/types" - - cfg "github.com/tendermint/tendermint/config" - tmTypes "github.com/tendermint/tendermint/types" ) const ( @@ -48,6 +48,8 @@ const ( // heimdall-config flags MainRPCUrlFlag = "eth_rpc_url" BorRPCUrlFlag = "bor_rpc_url" + BorGRPCUrlFlag = "bor_grpc_url" + BorGRPCFlag = "bor_grpc_flag" TendermintNodeURLFlag = "tendermint_rpc_url" HeimdallServerURLFlag = "heimdall_rest_server" AmqpURLFlag = "amqp_url" @@ -81,6 +83,7 @@ const ( // RPC Endpoints DefaultMainRPCUrl = "http://localhost:9545" DefaultBorRPCUrl = "http://localhost:8545" + DefaultBorGRPCUrl = "http://localhost:3131" // RPC Timeouts DefaultEthRPCTimeout = 5 * time.Second @@ -168,6 +171,8 @@ func init() { type Configuration struct { EthRPCUrl string `mapstructure:"eth_rpc_url"` // RPC endpoint for main chain BorRPCUrl string `mapstructure:"bor_rpc_url"` // RPC endpoint for bor chain + BorGRPCUrl string `mapstructure:"bor_grpc_url"` // gRPC endpoint for bor chain + BorGRPCFlag bool `mapstructure:"bor_grpc_flag"` // gRPC flag for bor chain TendermintRPCUrl string `mapstructure:"tendermint_rpc_url"` // tendemint node url SubGraphUrl string `mapstructure:"sub_graph_url"` // sub graph url @@ -213,6 +218,7 @@ var mainRPCClient *rpc.Client // MaticClient stores eth/rpc client for Matic Network var maticClient *ethclient.Client var maticRPCClient *rpc.Client +var maticGRPCClient *borgrpc.BorGRPCClient // private key object var privObject secp256k1.PrivKeySecp256k1 @@ -275,7 +281,7 @@ func InitHeimdallConfigWith(homeDir string, heimdallConfigFileFromFLag string) { return } - if strings.Compare(conf.BorRPCUrl, "") != 0 { + if strings.Compare(conf.BorRPCUrl, "") != 0 || strings.Compare(conf.BorGRPCUrl, "") != 0 { return } @@ -377,6 +383,9 @@ func InitHeimdallConfigWith(homeDir string, heimdallConfigFileFromFLag string) { } maticClient = ethclient.NewClient(maticRPCClient) + + maticGRPCClient = borgrpc.NewBorGRPCClient(conf.BorGRPCUrl) + // Loading genesis doc genDoc, err := tmTypes.GenesisDocFromFile(filepath.Join(configDir, "genesis.json")) if err != nil { @@ -424,6 +433,7 @@ func GetDefaultHeimdallConfig() Configuration { return Configuration{ EthRPCUrl: DefaultMainRPCUrl, BorRPCUrl: DefaultBorRPCUrl, + BorGRPCUrl: DefaultBorGRPCUrl, TendermintRPCUrl: DefaultTendermintNodeURL, EthRPCTimeout: DefaultEthRPCTimeout, @@ -506,6 +516,11 @@ func GetMaticRPCClient() *rpc.Client { return maticRPCClient } +// GetMaticGRPCClient returns matic's gRPC client +func GetMaticGRPCClient() *borgrpc.BorGRPCClient { + return maticGRPCClient +} + // GetPrivKey returns priv key object func GetPrivKey() secp256k1.PrivKeySecp256k1 { return privObject @@ -608,6 +623,27 @@ func DecorateWithHeimdallFlags(cmd *cobra.Command, v *viper.Viper, loggerInstanc loggerInstance.Error(fmt.Sprintf("%v | BindPFlag | %v", caller, BorRPCUrlFlag), "Error", err) } + // add BorGRPCUrlFlag flag + cmd.PersistentFlags().String( + BorGRPCUrlFlag, + "", + "Set gRPC endpoint for bor chain", + ) + + if err := v.BindPFlag(BorGRPCUrlFlag, cmd.PersistentFlags().Lookup(BorGRPCUrlFlag)); err != nil { + loggerInstance.Error(fmt.Sprintf("%v | BindPFlag | %v", caller, BorGRPCUrlFlag), "Error", err) + } + + cmd.PersistentFlags().Bool( + BorGRPCFlag, + false, + "Set if heimdall will use gRPC or Rest to interact with bor chain", + ) + + if err := v.BindPFlag(BorGRPCFlag, cmd.PersistentFlags().Lookup(BorGRPCFlag)); err != nil { + loggerInstance.Error(fmt.Sprintf("%v | BindPFlag | %v", caller, BorGRPCFlag), "Error", err) + } + // add TendermintNodeURLFlag flag cmd.PersistentFlags().String( TendermintNodeURLFlag, @@ -778,6 +814,18 @@ func (c *Configuration) UpdateWithFlags(v *viper.Viper, loggerInstance logger.Lo c.BorRPCUrl = stringConfgValue } + // get endpoint for bor chain from viper/cobra + stringConfgValue = v.GetString(BorGRPCUrlFlag) + if stringConfgValue != "" { + c.BorGRPCUrl = stringConfgValue + } + + // get gRPC flag for bor chain from viper/cobra + boolConfgValue := v.GetBool(BorGRPCFlag) + if boolConfgValue { + c.BorGRPCFlag = boolConfgValue + } + // get endpoint for tendermint from viper/cobra stringConfgValue = v.GetString(TendermintNodeURLFlag) if stringConfgValue != "" { @@ -897,6 +945,10 @@ func (c *Configuration) Merge(cc *Configuration) { c.BorRPCUrl = cc.BorRPCUrl } + if cc.BorGRPCUrl != "" { + c.BorGRPCUrl = cc.BorGRPCUrl + } + if cc.TendermintRPCUrl != "" { c.TendermintRPCUrl = cc.TendermintRPCUrl } diff --git a/helper/toml.go b/helper/toml.go index 3a6c8fce7..ceb898577 100644 --- a/helper/toml.go +++ b/helper/toml.go @@ -20,6 +20,12 @@ eth_rpc_url = "{{ .EthRPCUrl }}" # RPC endpoint for bor chain bor_rpc_url = "{{ .BorRPCUrl }}" +# GRPC flag for bor chain +bor_grpc_flag = "{{ .BorGRPCFlag }}" + +# GRPC endpoint for bor chain +bor_grpc_url = "{{ .BorGRPCUrl }}" + # RPC endpoint for tendermint tendermint_rpc_url = "{{ .TendermintRPCUrl }}"