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 }