github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/rpc/core/net.go (about)

     1  package core
     2  
     3  import (
     4  	ctypes "github.com/gnolang/gno/tm2/pkg/bft/rpc/core/types"
     5  	rpctypes "github.com/gnolang/gno/tm2/pkg/bft/rpc/lib/types"
     6  	"github.com/gnolang/gno/tm2/pkg/errors"
     7  )
     8  
     9  // Get network info.
    10  //
    11  // ```shell
    12  // curl 'localhost:26657/net_info'
    13  // ```
    14  //
    15  // ```go
    16  // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
    17  // err := client.Start()
    18  //
    19  //	if err != nil {
    20  //	  // handle error
    21  //	}
    22  //
    23  // defer client.Stop()
    24  // info, err := client.NetInfo()
    25  // ```
    26  //
    27  // > The above command returns JSON structured like this:
    28  //
    29  // ```json
    30  //
    31  //	{
    32  //	  "jsonrpc": "2.0",
    33  //	  "id": "",
    34  //	  "result": {
    35  //	  	"listening": true,
    36  //	  	"listeners": [
    37  //	  		"Listener(@)"
    38  //	  	],
    39  //	  	"n_peers": "3",
    40  //	  	"peers": [
    41  //	  		{
    42  //	  			"node_info": {
    43  //	  				"protocol_version": {
    44  //	  					"p2p": "7",
    45  //	  					"block": "8",
    46  //	  					"app": "1"
    47  //	  				},
    48  //	  				"id": "93529da3435c090d02251a050342b6a488d4ab56",
    49  //	  				"listen_addr": "tcp://0.0.0.0:26656",
    50  //	  				"network": "chain-RFo6qC",
    51  //	  				"version": "0.30.0",
    52  //	  				"channels": "4020212223303800",
    53  //	  				"moniker": "fc89e4ed23f2",
    54  //	  				"other": {
    55  //	  					"tx_index": "on",
    56  //	  					"rpc_address": "tcp://0.0.0.0:26657"
    57  //	  				}
    58  //	  			},
    59  //	  			"is_outbound": true,
    60  //	  			"connection_status": {
    61  //	  				"Duration": "3475230558",
    62  //	  				"SendMonitor": {
    63  //	  					"Active": true,
    64  //	  					"Start": "2019-02-14T12:40:47.52Z",
    65  //	  					"Duration": "3480000000",
    66  //	  					"Idle": "240000000",
    67  //	  					"Bytes": "4512",
    68  //	  					"Samples": "9",
    69  //	  					"InstRate": "1338",
    70  //	  					"CurRate": "2046",
    71  //	  					"AvgRate": "1297",
    72  //	  					"PeakRate": "6570",
    73  //	  					"BytesRem": "0",
    74  //	  					"TimeRem": "0",
    75  //	  					"Progress": 0
    76  //	  				},
    77  //	  				"RecvMonitor": {
    78  //	  					"Active": true,
    79  //	  					"Start": "2019-02-14T12:40:47.52Z",
    80  //	  					"Duration": "3480000000",
    81  //	  					"Idle": "280000000",
    82  //	  					"Bytes": "4489",
    83  //	  					"Samples": "10",
    84  //	  					"InstRate": "1821",
    85  //	  					"CurRate": "1663",
    86  //	  					"AvgRate": "1290",
    87  //	  					"PeakRate": "5512",
    88  //	  					"BytesRem": "0",
    89  //	  					"TimeRem": "0",
    90  //	  					"Progress": 0
    91  //	  				},
    92  //	  				"Channels": [
    93  //	  					{
    94  //	  						"ID": 48,
    95  //	  						"SendQueueCapacity": "1",
    96  //	  						"SendQueueSize": "0",
    97  //	  						"Priority": "5",
    98  //	  						"RecentlySent": "0"
    99  //	  					},
   100  //	  					{
   101  //	  						"ID": 64,
   102  //	  						"SendQueueCapacity": "1000",
   103  //	  						"SendQueueSize": "0",
   104  //	  						"Priority": "10",
   105  //	  						"RecentlySent": "14"
   106  //	  					},
   107  //	  					{
   108  //	  						"ID": 32,
   109  //	  						"SendQueueCapacity": "100",
   110  //	  						"SendQueueSize": "0",
   111  //	  						"Priority": "5",
   112  //	  						"RecentlySent": "619"
   113  //	  					},
   114  //	  					{
   115  //	  						"ID": 33,
   116  //	  						"SendQueueCapacity": "100",
   117  //	  						"SendQueueSize": "0",
   118  //	  						"Priority": "10",
   119  //	  						"RecentlySent": "1363"
   120  //	  					},
   121  //	  					{
   122  //	  						"ID": 34,
   123  //	  						"SendQueueCapacity": "100",
   124  //	  						"SendQueueSize": "0",
   125  //	  						"Priority": "5",
   126  //	  						"RecentlySent": "2145"
   127  //	  					},
   128  //	  					{
   129  //	  						"ID": 35,
   130  //	  						"SendQueueCapacity": "2",
   131  //	  						"SendQueueSize": "0",
   132  //	  						"Priority": "1",
   133  //	  						"RecentlySent": "0"
   134  //	  					},
   135  //	  					{
   136  //	  						"ID": 56,
   137  //	  						"SendQueueCapacity": "1",
   138  //	  						"SendQueueSize": "0",
   139  //	  						"Priority": "5",
   140  //	  						"RecentlySent": "0"
   141  //	  					},
   142  //	  					{
   143  //	  						"ID": 0,
   144  //	  						"SendQueueCapacity": "10",
   145  //	  						"SendQueueSize": "0",
   146  //	  						"Priority": "1",
   147  //	  						"RecentlySent": "10"
   148  //	  					}
   149  //	  				]
   150  //	  			},
   151  //	  			"remote_ip": "192.167.10.3"
   152  //	  		},
   153  //	     ...
   154  //	  }
   155  //
   156  // ```
   157  func NetInfo(ctx *rpctypes.Context) (*ctypes.ResultNetInfo, error) {
   158  	out, in, _ := p2pPeers.NumPeers()
   159  	peers := make([]ctypes.Peer, 0, out+in)
   160  	for _, peer := range p2pPeers.Peers().List() {
   161  		nodeInfo := peer.NodeInfo()
   162  		peers = append(peers, ctypes.Peer{
   163  			NodeInfo:         nodeInfo,
   164  			IsOutbound:       peer.IsOutbound(),
   165  			ConnectionStatus: peer.Status(),
   166  			RemoteIP:         peer.RemoteIP().String(),
   167  		})
   168  	}
   169  	// TODO: Should we include PersistentPeers and Seeds in here?
   170  	// PRO: useful info
   171  	// CON: privacy
   172  	return &ctypes.ResultNetInfo{
   173  		Listening: p2pTransport.IsListening(),
   174  		Listeners: p2pTransport.Listeners(),
   175  		NPeers:    len(peers),
   176  		Peers:     peers,
   177  	}, nil
   178  }
   179  
   180  func UnsafeDialSeeds(ctx *rpctypes.Context, seeds []string) (*ctypes.ResultDialSeeds, error) {
   181  	if len(seeds) == 0 {
   182  		return &ctypes.ResultDialSeeds{}, errors.New("No seeds provided")
   183  	}
   184  	logger.Info("DialSeeds", "seeds", seeds)
   185  	if err := p2pPeers.DialPeersAsync(seeds); err != nil {
   186  		return &ctypes.ResultDialSeeds{}, err
   187  	}
   188  	return &ctypes.ResultDialSeeds{Log: "Dialing seeds in progress. See /net_info for details"}, nil
   189  }
   190  
   191  func UnsafeDialPeers(ctx *rpctypes.Context, peers []string, persistent bool) (*ctypes.ResultDialPeers, error) {
   192  	if len(peers) == 0 {
   193  		return &ctypes.ResultDialPeers{}, errors.New("No peers provided")
   194  	}
   195  	logger.Info("DialPeers", "peers", peers, "persistent", persistent)
   196  	if persistent {
   197  		if err := p2pPeers.AddPersistentPeers(peers); err != nil {
   198  			return &ctypes.ResultDialPeers{}, err
   199  		}
   200  	}
   201  	if err := p2pPeers.DialPeersAsync(peers); err != nil {
   202  		return &ctypes.ResultDialPeers{}, err
   203  	}
   204  	return &ctypes.ResultDialPeers{Log: "Dialing peers in progress. See /net_info for details"}, nil
   205  }
   206  
   207  // Get genesis file.
   208  //
   209  // ```shell
   210  // curl 'localhost:26657/genesis'
   211  // ```
   212  //
   213  // ```go
   214  // client := client.NewHTTP("tcp://0.0.0.0:26657", "/websocket")
   215  // err := client.Start()
   216  //
   217  //	if err != nil {
   218  //	  // handle error
   219  //	}
   220  //
   221  // defer client.Stop()
   222  // genesis, err := client.Genesis()
   223  // ```
   224  //
   225  // > The above command returns JSON structured like this:
   226  //
   227  // ```json
   228  //
   229  //	{
   230  //		"error": "",
   231  //		"result": {
   232  //			"genesis": {
   233  //				"app_hash": "",
   234  //				"validators": [
   235  //					{
   236  //						"name": "",
   237  //						"power": "10",
   238  //						"pub_key": {
   239  //							"data": "68DFDA7E50F82946E7E8546BED37944A422CD1B831E70DF66BA3B8430593944D",
   240  //							"type": "ed25519"
   241  //						}
   242  //					}
   243  //				],
   244  //				"chain_id": "test-chain-6UTNIN",
   245  //				"genesis_time": "2017-05-29T15:05:41.671Z"
   246  //			}
   247  //		},
   248  //		"id": "",
   249  //		"jsonrpc": "2.0"
   250  //	}
   251  //
   252  // ```
   253  func Genesis(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) {
   254  	return &ctypes.ResultGenesis{Genesis: genDoc}, nil
   255  }