github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/common/monitor/tendermint.go (about)

     1  package monitor
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server"
     6  	tmcli "github.com/fibonacci-chain/fbc/libs/tendermint/rpc/client"
     7  	tmhttp "github.com/fibonacci-chain/fbc/libs/tendermint/rpc/client/http"
     8  	"github.com/spf13/viper"
     9  	"strings"
    10  	"sync"
    11  )
    12  
    13  const (
    14  	loopBackAddr = "tcp://127.0.0.1"
    15  )
    16  
    17  var (
    18  	tmMonitor     *TendermintMonitor
    19  	initTmMonitor sync.Once
    20  )
    21  
    22  // GetTendermintMonitor gets the global instance of TendermintMonitor
    23  func GetTendermintMonitor() *TendermintMonitor {
    24  	initTmMonitor.Do(func() {
    25  		tmMonitor = NewTendermintMonitor(viper.GetString(server.FlagLocalRpcPort))
    26  	})
    27  
    28  	return tmMonitor
    29  }
    30  
    31  // TendermintMonitor - structure of monitor for block/mempool monitoring
    32  type TendermintMonitor struct {
    33  	enable    bool
    34  	rpcClient tmcli.Client
    35  	status    tendermintStatus
    36  }
    37  
    38  // NewTendermintMonitor creates a new instance of TendermintMonitor
    39  func NewTendermintMonitor(portInput string) *TendermintMonitor {
    40  	if len(portInput) == 0 {
    41  		// disable the tendermint monitor
    42  		return &TendermintMonitor{
    43  			enable: false,
    44  		}
    45  	}
    46  
    47  	rpcCli, err := tmhttp.New(fmt.Sprintf("%s:%d", loopBackAddr, ParsePort(portInput)), "/websocket")
    48  	if err != nil {
    49  		panic(fmt.Sprintf("fail to init a rpc client in tendermint monitor: %s", err.Error()))
    50  	}
    51  
    52  	return &TendermintMonitor{
    53  		enable:    true,
    54  		rpcClient: rpcCli,
    55  	}
    56  }
    57  
    58  // reset resets the status of TendermintMonitor
    59  func (tm *TendermintMonitor) reset() {
    60  	tm.status.blockSize = -1
    61  	tm.status.uncomfirmedTxNum = -1
    62  	tm.status.uncormfirmedTxTotalSize = -1
    63  }
    64  
    65  // Run starts monitoring
    66  func (tm *TendermintMonitor) Run(height int64) error {
    67  	// TendermintMonitor disabled
    68  	if !tm.enable {
    69  		return nil
    70  	}
    71  
    72  	tm.reset()
    73  	err := tm.getTendermintStatus(height)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	return nil
    79  }
    80  
    81  // GetResultString gets the format string result
    82  func (tm *TendermintMonitor) GetResultString() string {
    83  	// TendermintMonitor disabled
    84  	if !tm.enable {
    85  		return ""
    86  	}
    87  
    88  	return fmt.Sprintf(",BlockSize<%.2fKB>, MemPoolTx<%d>, MemPoolSize<%.2fKB>,",
    89  		float64(tm.status.blockSize)/1024,
    90  		tm.status.uncomfirmedTxNum,
    91  		float64(tm.status.uncormfirmedTxTotalSize)/1024)
    92  }
    93  
    94  type tendermintStatus struct {
    95  	blockSize               int
    96  	uncomfirmedTxNum        int
    97  	uncormfirmedTxTotalSize int64
    98  }
    99  
   100  func (tm *TendermintMonitor) getTendermintStatus(height int64) error {
   101  	block, err := tm.rpcClient.Block(&height)
   102  	if err != nil {
   103  		return fmt.Errorf("failed to query block on height %d", height)
   104  	}
   105  
   106  	uncomfirmedRes, err := tm.rpcClient.NumUnconfirmedTxs()
   107  	if err != nil {
   108  		return fmt.Errorf("failed to query mempool result on height %d", height)
   109  	}
   110  
   111  	// update status
   112  	tm.status.blockSize = block.Block.Size()
   113  	tm.status.uncomfirmedTxNum = uncomfirmedRes.Total
   114  	tm.status.uncormfirmedTxTotalSize = uncomfirmedRes.TotalBytes
   115  
   116  	return nil
   117  }
   118  
   119  // CombineMonitorsRes combines all the monitors' results
   120  func CombineMonitorsRes(res ...string) string {
   121  	var builder strings.Builder
   122  	for _, r := range res {
   123  		builder.WriteString(r)
   124  	}
   125  
   126  	return strings.Trim(strings.TrimSpace(builder.String()), ",")
   127  }