parent
02e594f826
commit
476000193f
2 changed files with 91 additions and 3 deletions
90
rpcserver.go
90
rpcserver.go
|
@ -65,6 +65,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
|||
"gethashespersec": handleGetHashesPerSec,
|
||||
"getinfo": handleGetInfo,
|
||||
"getnettotals": handleGetNetTotals,
|
||||
"getnetworkhashps": handleGetNetworkHashPS,
|
||||
"getpeerinfo": handleGetPeerInfo,
|
||||
"getrawmempool": handleGetRawMempool,
|
||||
"getrawtransaction": handleGetRawTransaction,
|
||||
|
@ -134,7 +135,6 @@ var rpcAskWallet = map[string]bool{
|
|||
// Commands that are temporarily unimplemented.
|
||||
var rpcUnimplemented = map[string]bool{
|
||||
"getmininginfo": true,
|
||||
"getnetworkhashps": true,
|
||||
}
|
||||
|
||||
// rpcServer holds the items the rpc server may need to access (config,
|
||||
|
@ -989,6 +989,94 @@ func handleGetNetTotals(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
|||
return reply, nil
|
||||
}
|
||||
|
||||
// handleGetNetworkHashPS implements the getnetworkhashps command.
|
||||
func handleGetNetworkHashPS(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||
c := cmd.(*btcjson.GetNetworkHashPSCmd)
|
||||
|
||||
_, newestHeight, err := s.server.db.NewestSha()
|
||||
if err != nil {
|
||||
return nil, btcjson.Error{
|
||||
Code: btcjson.ErrInternal.Code,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
// When the passed height is too high or zero, just return 0 now
|
||||
// since we can't reasonably calculate the number of network hashes
|
||||
// per second from invalid values. When it's negative, use the current
|
||||
// best block height.
|
||||
endHeight := int64(c.Height)
|
||||
if endHeight > newestHeight || endHeight == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if endHeight < 0 {
|
||||
endHeight = newestHeight
|
||||
}
|
||||
|
||||
// Calculate the starting block height based on the passed number of
|
||||
// blocks. When the passed value is negative, use the last block the
|
||||
// difficulty changed as the starting height. Also make sure the
|
||||
// starting height is not before the beginning of the chain.
|
||||
var startHeight int64
|
||||
if c.Blocks <= 0 {
|
||||
startHeight = endHeight - ((endHeight % btcchain.BlocksPerRetarget) + 1)
|
||||
} else {
|
||||
startHeight = endHeight - int64(c.Blocks)
|
||||
}
|
||||
if startHeight < 0 {
|
||||
startHeight = 0
|
||||
}
|
||||
rpcsLog.Debugf("Calculating network hashes per second from %d to %d",
|
||||
startHeight, endHeight)
|
||||
|
||||
// Find the min and max block timestamps as well as calculate the total
|
||||
// amount of work that happened between the start and end blocks.
|
||||
var minTimestamp, maxTimestamp time.Time
|
||||
totalWork := big.NewInt(0)
|
||||
for curHeight := startHeight; curHeight <= endHeight; curHeight++ {
|
||||
hash, err := s.server.db.FetchBlockShaByHeight(curHeight)
|
||||
if err != nil {
|
||||
return nil, btcjson.Error{
|
||||
Code: btcjson.ErrInternal.Code,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
header, err := s.server.db.FetchBlockHeaderBySha(hash)
|
||||
if err != nil {
|
||||
return nil, btcjson.Error{
|
||||
Code: btcjson.ErrInternal.Code,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
if curHeight == startHeight {
|
||||
minTimestamp = header.Timestamp
|
||||
maxTimestamp = minTimestamp
|
||||
} else {
|
||||
totalWork.Add(totalWork, btcchain.CalcWork(header.Bits))
|
||||
|
||||
if minTimestamp.After(header.Timestamp) {
|
||||
minTimestamp = header.Timestamp
|
||||
}
|
||||
if maxTimestamp.Before(header.Timestamp) {
|
||||
maxTimestamp = header.Timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the difference in seconds between the min and max block
|
||||
// timestamps and avoid division by zero in the case where there is no
|
||||
// time difference.
|
||||
timeDiff := int64(maxTimestamp.Sub(minTimestamp) / time.Second)
|
||||
if timeDiff == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
hashesPerSec := new(big.Int).Div(totalWork, big.NewInt(timeDiff))
|
||||
return hashesPerSec.Int64(), nil
|
||||
}
|
||||
|
||||
// handleGetPeerInfo implements the getpeerinfo command.
|
||||
func handleGetPeerInfo(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||
return s.server.PeerInfo(), nil
|
||||
|
|
|
@ -160,7 +160,7 @@ func displayGeneric(reply interface{}) error {
|
|||
}
|
||||
|
||||
// displayFloat64 is a displayHandler that ensures the concrete type of the
|
||||
// passed interface is a float64 and displays it using fmt.Println. An error
|
||||
// passed interface is a float64 and displays it using fmt.Printf. An error
|
||||
// is returned if a float64 is not passed.
|
||||
func displayFloat64(reply interface{}) error {
|
||||
if val, ok := reply.(float64); ok {
|
||||
|
|
Loading…
Reference in a new issue