Skip to content

Commit

Permalink
Add missing function in Node API
Browse files Browse the repository at this point in the history
  • Loading branch information
quentinlesceller committed Jul 14, 2020
1 parent 1575cc7 commit 2a6d611
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 18 deletions.
72 changes: 62 additions & 10 deletions client/node_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import (
log "github.com/sirupsen/logrus"
)

// API struct
type grinAPI struct {
// GrinAPI struct
type GrinAPI struct {
GrinServerAPI string
}

// GetBlockReward queries the node to get the block reward with fees
func (grinAPI *grinAPI) GetBlockReward(blockHash string) (uint64, error) {
func (grinAPI *GrinAPI) GetBlockReward(blockHash string) (uint64, error) {
block, err := grinAPI.GetBlockByHash(blockHash)
if err != nil {
return 0, err
Expand All @@ -44,7 +44,7 @@ func (grinAPI *grinAPI) GetBlockReward(blockHash string) (uint64, error) {
}

// GetBlockByHash returns a block using the hash
func (grinAPI *grinAPI) GetBlockByHash(blockHash string) (*api.BlockPrintable, error) {
func (grinAPI *GrinAPI) GetBlockByHash(blockHash string) (*api.BlockPrintable, error) {
var block api.BlockPrintable
url := "http://" + grinAPI.GrinServerAPI + "/v1/blocks/" + blockHash
if err := getJSON(url, &block); err != nil {
Expand All @@ -59,8 +59,8 @@ func (grinAPI *grinAPI) GetBlockByHash(blockHash string) (*api.BlockPrintable, e
return &block, nil
}

// GetBlockByHash returns a block using the height
func (grinAPI *grinAPI) GetBlockByHeight(height uint64) (*api.BlockPrintable, error) {
// GetBlockByHeight returns a block using the height
func (grinAPI *GrinAPI) GetBlockByHeight(height uint64) (*api.BlockPrintable, error) {
var block api.BlockPrintable
url := fmt.Sprintf("http://%s/v1/blocks/%d", grinAPI.GrinServerAPI, height)
if err := getJSON(url, &block); err != nil {
Expand All @@ -75,8 +75,8 @@ func (grinAPI *grinAPI) GetBlockByHeight(height uint64) (*api.BlockPrintable, er
return &block, nil
}

// GetBlockByHash returns a block using the hash
func (grinAPI *grinAPI) GetStatus() (*api.Status, error) {
// GetStatus returns the node status
func (grinAPI *GrinAPI) GetStatus() (*api.Status, error) {
var status api.Status
url := "http://" + grinAPI.GrinServerAPI + "/v1/status"
if err := getJSON(url, &status); err != nil {
Expand All @@ -85,7 +85,8 @@ func (grinAPI *grinAPI) GetStatus() (*api.Status, error) {
return &status, nil
}

func (grinAPI *grinAPI) GetTargetDifficultyAndHashrates(status *api.Status) (uint64, float64, float64, error) {
// GetTargetDifficultyAndHashrates returns the target difficulty and hashrate
func (grinAPI *GrinAPI) GetTargetDifficultyAndHashrates(status *api.Status) (uint64, float64, float64, error) {
if status == nil {
return 0, 0, 0, fmt.Errorf("status is nil")
}
Expand Down Expand Up @@ -115,8 +116,40 @@ func (grinAPI *grinAPI) GetTargetDifficultyAndHashrates(status *api.Status) (uin
return targetDifficulty, primaryHashrate, secondaryHashrate, nil
}

// GetTargetDifficultyAndAllHashrates retrieve the target difficulty and hashrate
// different from the function above as it send back ALL the hashrates (c29,c31...)
func (grinAPI *GrinAPI) GetTargetDifficultyAndAllHashrates(status *api.Status) (uint64, map[uint8]float64, error) {
if status == nil {
return 0, nil, fmt.Errorf("status is nil")
}
lastBlock, err := grinAPI.GetBlockByHash(status.Tip.LastBlockPushed)
if err != nil {
log.WithFields(log.Fields{
"error": err,
}).Error("API: Cannot get last block from Grin Node API")
return 0, nil, fmt.Errorf("API: Cannot get last block from Grin Node API: %s", err)
}
previousBlock, err := grinAPI.GetBlockByHash(status.Tip.PrevBlockToLast)
if err != nil {
log.WithFields(log.Fields{
"error": err,
}).Error("API: Cannot get previous block from Grin Node API")
return 0, nil, fmt.Errorf("API: Cannot get previous block from Grin Node API: %s", err)
}
targetDifficulty := lastBlock.Header.TotalDifficulty - previousBlock.Header.TotalDifficulty

hashrates, err := grinAPI.computeAllHashrates(lastBlock.Header.Height)
if err != nil {
log.WithFields(log.Fields{
"error": err,
}).Error("API: Cannot compute hashrates")
return 0, nil, fmt.Errorf("API: Cannot compute hashrates: %s", err)
}
return targetDifficulty, hashrates, nil
}

// computePrimarySecondaryNetworkHashrates is a shameless copy of https://github.com/grin-pool/grin-pool/blob/f3e21651b26f759b5303e9f7f702a55d55f63ca4/grin-py/grinlib/grinstats.py#L93
func (grinAPI *grinAPI) computePrimarySecondaryNetworkHashrates(endHeight uint64) (float64, float64, error) {
func (grinAPI *GrinAPI) computePrimarySecondaryNetworkHashrates(endHeight uint64) (float64, float64, error) {
var blocks []api.BlockPrintable
var startHeight uint64
if endHeight < consensus.DifficultyAdjustWindow {
Expand Down Expand Up @@ -187,3 +220,22 @@ func estimateAllHashrates(blocks []api.BlockPrintable) (map[uint8]float64, error
}
return gpsMap, nil
}

func (grinAPI *GrinAPI) computeAllHashrates(endHeight uint64) (map[uint8]float64, error) {
var blocks []api.BlockPrintable
var startHeight uint64
if endHeight < consensus.DifficultyAdjustWindow {
startHeight = 0
}
startHeight = endHeight - consensus.DifficultyAdjustWindow
for height := startHeight; height <= endHeight; height++ {
block, err := grinAPI.GetBlockByHeight(height)
if err != nil {
return nil, err
}
blocks = append(blocks, *block)
}

return estimateAllHashrates(blocks)

}
17 changes: 9 additions & 8 deletions client/node_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package client
package client_test

import (
"context"
Expand All @@ -24,6 +24,7 @@ import (
"testing"

"github.com/blockcypher/libgrin/api"
"github.com/blockcypher/libgrin/client"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -117,12 +118,12 @@ func addBlock() {
blocks = append(blocks, block16112)
}

func nextAPI(increment int) (grinAPI, string) {
func nextAPI(increment int) (client.GrinAPI, string) {
var startPort = 23413
portInt := startPort + increment
port := strconv.Itoa(portInt)
addr := "127.0.0.1:" + port
return grinAPI{GrinServerAPI: addr}, addr
return client.GrinAPI{GrinServerAPI: addr}, addr
}

// The API used here
Expand Down Expand Up @@ -169,7 +170,7 @@ func TestGetBlockByHashMissing(t *testing.T) {
}

func TestGetBlockByHashUnreachable(t *testing.T) {
grinAPI := grinAPI{}
grinAPI := client.GrinAPI{}
var blockHash = "0822cd711993d0f9a3ffdb4e755defd84a40aa25ce72f8053fa330247a36f687"
block, err := grinAPI.GetBlockByHash(blockHash)
assert.Error(t, err)
Expand All @@ -196,7 +197,7 @@ func TestGetBlockByHeightMissing(t *testing.T) {
}

func TestGetBlockUnreachable(t *testing.T) {
grinAPI := grinAPI{}
grinAPI := client.GrinAPI{}
block, err := grinAPI.GetBlockByHeight(1619)
assert.Error(t, err)
assert.Nil(t, block)
Expand All @@ -217,7 +218,7 @@ func TestGetStatus(t *testing.T) {
}

func TestGetStatusUnreachable(t *testing.T) {
grinAPI := grinAPI{}
grinAPI := client.GrinAPI{}
status, err := grinAPI.GetStatus()
assert.Error(t, err)
assert.Nil(t, status)
Expand Down Expand Up @@ -255,7 +256,7 @@ func TestGetTargetDifficultyAndHashratesMissingPreviousBlock(t *testing.T) {
}

func TestGetTargetDifficultyAndHashratesUnreachable(t *testing.T) {
grinAPI := grinAPI{}
grinAPI := client.GrinAPI{}
status, err := grinAPI.GetStatus()
assert.Error(t, err)
td, _, h, err := grinAPI.GetTargetDifficultyAndHashrates(status)
Expand All @@ -267,7 +268,7 @@ func TestGetTargetDifficultyAndHashratesUnreachable(t *testing.T) {
}

func TestGetTargetDifficultyAndHashratesUnreachableAfter(t *testing.T) {
grinAPI := grinAPI{}
grinAPI := client.GrinAPI{}
status := api.Status{ProtocolVersion: 1}
td, _, h, err := grinAPI.GetTargetDifficultyAndHashrates(&status)
assert.Error(t, err)
Expand Down

0 comments on commit 2a6d611

Please sign in to comment.