diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 4feaeda338e..bc7be655a09 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -117,6 +117,19 @@ type GetBlockVerboseTxResult struct { NextHash string `json:"nextblockhash,omitempty"` } +// ChainTip is a single chain tip. +type ChainTip struct { + Height int32 `json:"height"` + Hash string `json:"hash"` + BranchLen int32 `json:"branchlen"` + Status string `json:"status"` +} + +// GetChainTipsResult models the data from the getchaintips command. +type GetChainTipsResult struct { + ChainTips []ChainTip `json:"chaintips"` +} + // GetChainTxStatsResult models the data from the getchaintxstats command. type GetChainTxStatsResult struct { Time int64 `json:"time"` diff --git a/rpcserver.go b/rpcserver.go index b917263df51..ca1d24e663f 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -146,6 +146,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getblockhash": handleGetBlockHash, "getblockheader": handleGetBlockHeader, "getblocktemplate": handleGetBlockTemplate, + "getchaintips": handleGetChainTips, "getcfilter": handleGetCFilter, "getcfilterheader": handleGetCFilterHeader, "getconnectioncount": handleGetConnectionCount, @@ -231,7 +232,6 @@ var rpcAskWallet = map[string]struct{}{ // Commands that are currently unimplemented, but should ultimately be. var rpcUnimplemented = map[string]struct{}{ "estimatepriority": {}, - "getchaintips": {}, "getmempoolentry": {}, "getnetworkinfo": {}, "getwork": {}, @@ -266,6 +266,7 @@ var rpcLimited = map[string]struct{}{ "getblockcount": {}, "getblockhash": {}, "getblockheader": {}, + "getchaintips": {}, "getcfilter": {}, "getcfilterheader": {}, "getcurrentnet": {}, @@ -2192,6 +2193,24 @@ func handleGetBlockTemplate(s *rpcServer, cmd interface{}, closeChan <-chan stru } } +// handleGetChainTips implements the getchaintips command. +func handleGetChainTips(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { + chainTips := s.cfg.Chain.ChainTips() + + ret := btcjson.GetChainTipsResult{} + for _, chainTip := range chainTips { + ret.ChainTips = append(ret.ChainTips, + btcjson.ChainTip{ + Height: chainTip.Height, + Hash: chainTip.BlockHash.String(), + BranchLen: chainTip.BranchLen, + Status: chainTip.Status.String(), + }) + } + + return ret, nil +} + // handleGetCFilter implements the getcfilter command. func handleGetCFilter(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { if s.cfg.CfIndex == nil { diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 16bbb62a2b4..16215458afc 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -347,6 +347,18 @@ var helpDescsEnUS = map[string]string{ "getblocktemplate--condition2": "mode=proposal, accepted", "getblocktemplate--result1": "An error string which represents why the proposal was rejected or nothing if accepted", + // GetChainTipsResult help. + "getchaintipsresult-chaintips": "The chaintips that this node is aware of", + + // ChainTip help. + "chaintip-height": "The height of the chain tip", + "chaintip-hash": "The block hash of the chain tip", + "chaintip-branchlen": "Returns zero for main chain. Otherwise is the length of branch connecting the tip to the main chain", + "chaintip-status": "Status of the chain. Returns \"active\" for the main chain", + + // GetChainTipsCmd help. + "getchaintips--synopsis": "Returns information about all known tips in the block tree, including the main chain as well as orphaned branches.", + // GetCFilterCmd help. "getcfilter--synopsis": "Returns a block's committed filter given its hash.", "getcfilter-filtertype": "The type of filter to return (0=regular)", @@ -728,6 +740,7 @@ var rpcResultTypes = map[string][]interface{}{ "getblockheader": {(*string)(nil), (*btcjson.GetBlockHeaderVerboseResult)(nil)}, "getblocktemplate": {(*btcjson.GetBlockTemplateResult)(nil), (*string)(nil), nil}, "getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)}, + "getchaintips": {(*btcjson.GetChainTipsResult)(nil)}, "getcfilter": {(*string)(nil)}, "getcfilterheader": {(*string)(nil)}, "getconnectioncount": {(*int32)(nil)},