Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GetNodeVersionInfo API #662

Merged
merged 15 commits into from
May 23, 2024
3 changes: 3 additions & 0 deletions access/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type Client interface {
// GetNetworkParameters gets the network parameters.
GetNetworkParameters(ctx context.Context) (*flow.NetworkParameters, error)

// GetNodeVersionInfo gets the node information about the network.
GetNodeVersionInfo(ctx context.Context) (*flow.NodeVersionInfo, error)

// GetLatestBlockHeader gets the latest sealed or unsealed block header.
GetLatestBlockHeader(ctx context.Context, isSealed bool) (*flow.BlockHeader, error)

Expand Down
4 changes: 4 additions & 0 deletions access/grpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ func (c *Client) GetNetworkParameters(ctx context.Context) (*flow.NetworkParamet
return c.grpc.GetNetworkParameters(ctx)
}

func (c *Client) GetNodeVersionInfo(ctx context.Context) (*flow.NodeVersionInfo, error) {
return c.grpc.GetNodeVersionInfo(ctx)
}

func (c *Client) GetLatestBlockHeader(ctx context.Context, isSealed bool) (*flow.BlockHeader, error) {
return c.grpc.GetLatestBlockHeader(ctx, isSealed)
}
Expand Down
17 changes: 17 additions & 0 deletions access/grpc/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,23 @@ func (c *BaseClient) GetNetworkParameters(ctx context.Context, opts ...grpc.Call
}, nil
}

func (c *BaseClient) GetNodeVersionInfo(ctx context.Context, opts ...grpc.CallOption) (*flow.NodeVersionInfo, error) {
res, err := c.rpcClient.GetNodeVersionInfo(ctx, &access.GetNodeVersionInfoRequest{}, opts...)
if err != nil {
return nil, newRPCError(err)
}

info := res.GetInfo()
return &flow.NodeVersionInfo{
Semver: info.Semver,
Commit: info.Commit,
SporkId: flow.BytesToID(info.SporkId),
ProtocolVersion: info.ProtocolVersion,
SporkRootBlockHeight: info.SporkRootBlockHeight,
NodeRootBlockHeight: info.NodeRootBlockHeight,
}, nil
}

func (c *BaseClient) GetLatestBlockHeader(
ctx context.Context,
isSealed bool,
Expand Down
35 changes: 35 additions & 0 deletions access/grpc/grpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,41 @@ func TestClient_GetNetworkParameters(t *testing.T) {
}))
}

func TestClient_GetNodeInfo(t *testing.T) {
t.Run("Success", clientTest(func(t *testing.T, ctx context.Context, rpc *mocks.MockRPCClient, c *BaseClient) {
id := flow.HexToID("0x01")
ver := uint64(1)
spork := uint64(2)
root := uint64(3)

response := &access.GetNodeVersionInfoResponse{
Info: &entities.NodeVersionInfo{
Semver: "1.0",
Commit: "123",
SporkId: id.Bytes(),
ProtocolVersion: ver,
SporkRootBlockHeight: spork,
NodeRootBlockHeight: root,
},
}

expected := &flow.NodeVersionInfo{
Semver: "1.0",
Commit: "123",
SporkId: id,
ProtocolVersion: ver,
SporkRootBlockHeight: spork,
NodeRootBlockHeight: root,
}

rpc.On("GetNodeVersionInfo", ctx, mock.Anything).Return(response, nil)

info, err := c.GetNodeVersionInfo(ctx)
require.NoError(t, err)
require.Equal(t, expected, info)
}))
}

func TestClient_GetLatestBlockHeader(t *testing.T) {
blocks := test.BlockGenerator()

Expand Down
90 changes: 90 additions & 0 deletions access/grpc/mocks/ExecutionDataRPCClient.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions access/http/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ func (c *Client) GetNetworkParameters(ctx context.Context) (*flow.NetworkParamet
return c.httpClient.GetNetworkParameters(ctx)
}

func (c *Client) GetNodeVersionInfo(ctx context.Context) (*flow.NodeVersionInfo, error) {
return c.httpClient.GetNodeVersionInfo(ctx)
}

func (c *Client) GetBlockByID(ctx context.Context, blockID flow.Identifier) (*flow.Block, error) {
return c.httpClient.GetBlockByID(ctx, blockID)
}
Expand Down
25 changes: 25 additions & 0 deletions access/http/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"testing"

jsoncdc "github.com/onflow/cadence/encoding/json"
"github.com/stretchr/testify/require"

"github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go-sdk/access/http/models"
"github.com/onflow/flow-go-sdk/test"
Expand Down Expand Up @@ -79,6 +81,29 @@ func TestClient_ClientOptions(t *testing.T) {
})
}

func TestBaseClient_GetNodeInfo(t *testing.T) {
t.Run("Success", clientTest(func(ctx context.Context, t *testing.T, handler *mockHandler, client *Client) {
httpInfo := &models.NodeVersionInfo{
Semver: "1.0",
Commit: "123",
SporkId: flow.HexToID("0x01").String(),
ProtocolVersion: "2",
SporkRootBlockHeight: "123",
NodeRootBlockHeight: "321",
}
expectedInfo, err := toNodeVersionInfo(httpInfo)
require.NoError(t, err)

handler.
On("getNodeVersionInfo", mock.Anything).
Return(httpInfo, nil)

info, err := client.GetNodeVersionInfo(ctx)
require.NoError(t, err)
assert.Equal(t, expectedInfo, info)
}))
}

func TestBaseClient_GetNetworkParameters(t *testing.T) {
const handlerName = "getNetworkParameters"

Expand Down
34 changes: 29 additions & 5 deletions access/http/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,10 @@ func toTransactionResult(txr *models.TransactionResult, options []cadenceJSON.Op
}

return &flow.TransactionResult{
Status: toTransactionStatus(txr.Status),
Error: txErr,
Events: events,
BlockID: flow.HexToID(txr.BlockId),
Status: toTransactionStatus(txr.Status),
Error: txErr,
Events: events,
BlockID: flow.HexToID(txr.BlockId),
CollectionID: flow.HexToID(txr.CollectionId),
}, nil
}
Expand Down Expand Up @@ -446,4 +446,28 @@ func toNetworkParameters(params *models.NetworkParameters) *flow.NetworkParamete
return &flow.NetworkParameters{
ChainID: flow.ChainID(params.ChainId),
}
}
}

func toNodeVersionInfo(info *models.NodeVersionInfo) (*flow.NodeVersionInfo, error) {
version, err := strconv.ParseUint(info.ProtocolVersion, 10, 64)
if err != nil {
return nil, err
}
sporkHeight, err := strconv.ParseUint(info.SporkRootBlockHeight, 10, 64)
if err != nil {
return nil, err
}
nodeHeight, err := strconv.ParseUint(info.NodeRootBlockHeight, 10, 64)
if err != nil {
return nil, err
}

return &flow.NodeVersionInfo{
Semver: info.Semver,
Commit: info.Commit,
SporkId: flow.HexToID(info.SporkId),
ProtocolVersion: version,
SporkRootBlockHeight: sporkHeight,
NodeRootBlockHeight: nodeHeight,
}, nil
}
10 changes: 10 additions & 0 deletions access/http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,16 @@ func (h *httpHandler) getNetworkParameters(ctx context.Context, opts ...queryOpt
return &networkParameters, nil
}

func (h *httpHandler) getNodeVersionInfo(ctx context.Context, opts ...queryOpts) (*models.NodeVersionInfo, error) {
var nodeVersionInfo models.NodeVersionInfo
err := h.get(ctx, h.mustBuildURL("/node_version_info", opts...), &nodeVersionInfo)
if err != nil {
return nil, errors.Wrap(err, "get node version info failed")
}

return &nodeVersionInfo, nil
}

func (h *httpHandler) getBlockByID(ctx context.Context, ID string, opts ...queryOpts) (*models.Block, error) {
u := h.mustBuildURL(fmt.Sprintf("/blocks/%s", ID), opts...)

Expand Down
30 changes: 30 additions & 0 deletions access/http/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ import (
"strings"
"testing"

"github.com/stretchr/testify/require"

"github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go-sdk/access/http/models"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -118,6 +121,33 @@ func TestHandler_ResponseFailures(t *testing.T) {
}))
}

func TestHandler_GetNodeVersionInfo(t *testing.T) {
t.Run("success", handlerTest(func(ctx context.Context, t *testing.T, handler httpHandler, req *testRequest) {
id := flow.HexToID("0x01")
sporkHeight := uint64(1337)
rootHeight := uint64(222)

httpInfo := &models.NodeVersionInfo{
Semver: "1.0",
Commit: "123",
SporkId: id.String(),
ProtocolVersion: "2.0",
SporkRootBlockHeight: fmt.Sprintf("%d", sporkHeight),
NodeRootBlockHeight: fmt.Sprintf("%d", rootHeight),
}

u, err := url.Parse("/node_version_info")
require.NoError(t, err)

req.SetData(*u, httpInfo)

info, err := handler.getNodeVersionInfo(ctx)
require.NoError(t, err)
assert.Equal(t, httpInfo.SporkRootBlockHeight, info.SporkRootBlockHeight)
assert.Equal(t, httpInfo.SporkRootBlockHeight, info.SporkRootBlockHeight)
}))
}

func TestHandler_GetBlockByID(t *testing.T) {
t.Run("Success", handlerTest(func(ctx context.Context, t *testing.T, handler httpHandler, req *testRequest) {
b := blockFlowFixture()
Expand Down
10 changes: 10 additions & 0 deletions access/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
// handler interface defines methods needed to be offered by a specific http network implementation.
type handler interface {
getNetworkParameters(ctx context.Context, opts ...queryOpts) (*models.NetworkParameters, error)
getNodeVersionInfo(ctx context.Context, opts ...queryOpts) (*models.NodeVersionInfo, error)
getBlockByID(ctx context.Context, ID string, opts ...queryOpts) (*models.Block, error)
getBlocksByHeights(ctx context.Context, heights string, startHeight string, endHeight string, opts ...queryOpts) ([]*models.Block, error)
getAccount(ctx context.Context, address string, height string, opts ...queryOpts) (*models.Account, error)
Expand Down Expand Up @@ -197,6 +198,15 @@ func (c *BaseClient) GetNetworkParameters(ctx context.Context) (*flow.NetworkPar
return toNetworkParameters(params), nil
}

func (c *BaseClient) GetNodeVersionInfo(ctx context.Context) (*flow.NodeVersionInfo, error) {
info, err := c.handler.getNodeVersionInfo(ctx)
if err != nil {
return nil, err
}

return toNodeVersionInfo(info)
}

func (c *BaseClient) GetBlockByID(ctx context.Context, blockID flow.Identifier, opts ...queryOpts) (*flow.Block, error) {
block, err := c.handler.getBlockByID(ctx, blockID.String())
if err != nil {
Expand Down
30 changes: 30 additions & 0 deletions access/http/mock_handler.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading