From a4a79387ccaee79cb4d760bc53d05742d468cd98 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 3 May 2014 23:51:54 -0500 Subject: [PATCH] Add support for getmininginfo RPC. Closes #126. --- mempool.go | 11 +++++++++ rpcserver.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/mempool.go b/mempool.go index e39f6bee..cf609d1c 100644 --- a/mempool.go +++ b/mempool.go @@ -1039,6 +1039,17 @@ func (mp *txMemPool) ProcessTransaction(tx *btcutil.Tx, allowOrphan, rateLimit b return nil } +// Count returns the number of transactions in the main pool. It does not +// include the orphan pool. +// +// This function is safe for concurrent access. +func (mp *txMemPool) Count() int { + mp.RLock() + defer mp.RUnlock() + + return len(mp.pool) +} + // TxShas returns a slice of hashes for all of the transactions in the memory // pool. // diff --git a/rpcserver.go b/rpcserver.go index 2c1ebbb6..7addd599 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -90,6 +90,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getgenerate": handleGetGenerate, "gethashespersec": handleGetHashesPerSec, "getinfo": handleGetInfo, + "getmininginfo": handleGetMiningInfo, "getnettotals": handleGetNetTotals, "getnetworkhashps": handleGetNetworkHashPS, "getpeerinfo": handleGetPeerInfo, @@ -160,9 +161,7 @@ var rpcAskWallet = map[string]bool{ } // Commands that are temporarily unimplemented. -var rpcUnimplemented = map[string]bool{ - "getmininginfo": true, -} +var rpcUnimplemented = map[string]bool{} // workStateBlockInfo houses information about how to reconstruct a block given // its template and signature script. @@ -1132,6 +1131,66 @@ func handleGetInfo(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) { return ret, nil } +// handleGetMiningInfo implements the getmininginfo command. We only return the +// fields that are not related to wallet functionality. +func handleGetMiningInfo(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) { + sha, height, err := s.server.db.NewestSha() + if err != nil { + rpcsLog.Errorf("Error getting sha: %v", err) + return nil, btcjson.ErrBlockCount + } + block, err := s.server.db.FetchBlockBySha(sha) + if err != nil { + rpcsLog.Errorf("Error getting block: %v", err) + return nil, btcjson.ErrBlockNotFound + } + blockBytes, err := block.Bytes() + if err != nil { + rpcsLog.Errorf("Error getting block: %v", err) + return nil, btcjson.Error{ + Code: btcjson.ErrInternal.Code, + Message: err.Error(), + } + } + + // Create a default getnetworkhashps command to use defaults and make + // use of the existing getnetworkhashps handler. + gnhpsCmd, err := btcjson.NewGetNetworkHashPSCmd(0) + if err != nil { + return nil, btcjson.Error{ + Code: btcjson.ErrInternal.Code, + Message: err.Error(), + } + } + rpcsLog.Info(gnhpsCmd.Blocks, gnhpsCmd.Height) + networkHashesPerSecIface, err := handleGetNetworkHashPS(s, gnhpsCmd) + if err != nil { + // This is already a btcjson.Error from the handler. + return nil, err + } + networkHashesPerSec, ok := networkHashesPerSecIface.(int64) + if !ok { + return nil, btcjson.Error{ + Code: btcjson.ErrInternal.Code, + Message: "networkHashesPerSec is not an int64", + } + } + + result := &btcjson.GetMiningInfoResult{ + Blocks: height, + CurrentBlockSize: uint64(len(blockBytes)), + CurrentBlockTx: uint64(len(block.MsgBlock().Transactions)), + Difficulty: getDifficultyRatio(block.MsgBlock().Header.Bits), + Generate: false, // no built-in miner + GenProcLimit: -1, // no built-in miner + HashesPerSec: 0, // no built-in miner + NetworkHashPS: networkHashesPerSec, + PooledTx: uint64(s.server.txMemPool.Count()), + TestNet: cfg.TestNet3, + } + return &result, nil +} + // handleGetNetTotals implements the getnettotals command. func handleGetNetTotals(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) { totalBytesRecv, totalBytesSent := s.server.NetTotals()