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

feat(dot/rpc) Add system_syncState rpc call #1691

Merged
merged 7 commits into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions dot/network/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,3 +691,13 @@ func (s *Service) Peers() []common.PeerInfo {
func (s *Service) NodeRoles() byte {
return s.cfg.Roles
}

// HighestBlock returns the highest known block number
func (s *Service) HighestBlock() int64 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason why this isn't a uint64?

Copy link
Member Author

@EclesioMeloJunior EclesioMeloJunior Jul 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to keep the return type as the same type of syncQueue.currStart

return s.syncQueue.goal
}

// StartingBlock return the starting block number that's currently being synced
func (s *Service) StartingBlock() int64 {
return s.syncQueue.currStart
}
2 changes: 1 addition & 1 deletion dot/rpc/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (h *HTTPServer) RegisterModules(mods []string) {
switch mod {
case "system":
srvc = modules.NewSystemModule(h.serverConfig.NetworkAPI, h.serverConfig.SystemAPI,
h.serverConfig.CoreAPI, h.serverConfig.StorageAPI, h.serverConfig.TransactionQueueAPI)
h.serverConfig.CoreAPI, h.serverConfig.StorageAPI, h.serverConfig.TransactionQueueAPI, h.serverConfig.BlockAPI)
case "author":
srvc = modules.NewAuthorModule(h.logger, h.serverConfig.CoreAPI, h.serverConfig.RuntimeAPI, h.serverConfig.TransactionQueueAPI)
case "chain":
Expand Down
2 changes: 2 additions & 0 deletions dot/rpc/modules/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type NetworkAPI interface {
Stop() error
Start() error
IsStopped() bool
HighestBlock() int64
StartingBlock() int64
}

// BlockProducerAPI is the interface for BlockProducer methods
Expand Down
28 changes: 28 additions & 0 deletions dot/rpc/modules/mocks/network_api.go

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

26 changes: 25 additions & 1 deletion dot/rpc/modules/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type SystemModule struct {
coreAPI CoreAPI
storageAPI StorageAPI
txStateAPI TransactionStateAPI
blockAPI BlockAPI
}

// EmptyRequest represents an RPC request with no fields
Expand Down Expand Up @@ -69,15 +70,23 @@ type StringRequest struct {
String string
}

// SyncStateResponse is the struct to return on the system_syncState rpc call
type SyncStateResponse struct {
CurrentBlock uint32 `json:"currentBlock"`
HighestBlock uint32 `json:"highestBlock"`
StartingBlock uint32 `json:"startingBlock"`
}

// NewSystemModule creates a new API instance
func NewSystemModule(net NetworkAPI, sys SystemAPI, core CoreAPI,
storage StorageAPI, txAPI TransactionStateAPI) *SystemModule {
storage StorageAPI, txAPI TransactionStateAPI, blockAPI BlockAPI) *SystemModule {
return &SystemModule{
networkAPI: net, // TODO: migrate to network state
systemAPI: sys,
coreAPI: core,
storageAPI: storage,
txStateAPI: txAPI,
blockAPI: blockAPI,
}
}

Expand Down Expand Up @@ -228,6 +237,21 @@ func (sm *SystemModule) AccountNextIndex(r *http.Request, req *StringRequest, re
return nil
}

// SyncState Returns the state of the syncing of the node.
func (sm *SystemModule) SyncState(r *http.Request, req *EmptyRequest, res *SyncStateResponse) error {
h, err := sm.blockAPI.GetHeader(sm.blockAPI.BestBlockHash())
if err != nil {
return err
}

*res = SyncStateResponse{
CurrentBlock: uint32(h.Number.Int64()),
HighestBlock: uint32(sm.networkAPI.HighestBlock()),
StartingBlock: uint32(sm.networkAPI.StartingBlock()),
}
return nil
}

// LocalListenAddresses Returns the libp2p multiaddresses that the local node is listening on
func (sm *SystemModule) LocalListenAddresses(r *http.Request, req *EmptyRequest, res *[]string) error {
netstate := sm.networkAPI.NetworkState()
Expand Down
56 changes: 46 additions & 10 deletions dot/rpc/modules/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package modules

import (
"errors"
"fmt"
"math/big"
"os"
Expand Down Expand Up @@ -89,7 +90,7 @@ func newNetworkService(t *testing.T) *network.Service {
func TestSystemModule_Health(t *testing.T) {
net := newNetworkService(t)
net.Stop()
sys := NewSystemModule(net, nil, nil, nil, nil)
sys := NewSystemModule(net, nil, nil, nil, nil, nil)

res := &SystemHealthResponse{}
err := sys.Health(nil, nil, res)
Expand All @@ -103,7 +104,7 @@ func TestSystemModule_Health(t *testing.T) {
// Test RPC's System.NetworkState() response
func TestSystemModule_NetworkState(t *testing.T) {
net := newNetworkService(t)
sys := NewSystemModule(net, nil, nil, nil, nil)
sys := NewSystemModule(net, nil, nil, nil, nil, nil)

res := &SystemNetworkStateResponse{}
err := sys.NetworkState(nil, nil, res)
Expand All @@ -120,7 +121,7 @@ func TestSystemModule_NetworkState(t *testing.T) {
func TestSystemModule_Peers(t *testing.T) {
net := newNetworkService(t)
net.Stop()
sys := NewSystemModule(net, nil, nil, nil, nil)
sys := NewSystemModule(net, nil, nil, nil, nil, nil)

res := &SystemPeersResponse{}
err := sys.Peers(nil, nil, res)
Expand All @@ -133,7 +134,7 @@ func TestSystemModule_Peers(t *testing.T) {

func TestSystemModule_NodeRoles(t *testing.T) {
net := newNetworkService(t)
sys := NewSystemModule(net, nil, nil, nil, nil)
sys := NewSystemModule(net, nil, nil, nil, nil, nil)
expected := []interface{}{"Full"}

var res []interface{}
Expand Down Expand Up @@ -165,7 +166,7 @@ func newMockSystemAPI() *mocks.MockSystemAPI {
}

func TestSystemModule_Chain(t *testing.T) {
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil)
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil, nil)

res := new(string)
err := sys.Chain(nil, nil, res)
Expand All @@ -176,14 +177,14 @@ func TestSystemModule_Chain(t *testing.T) {
func TestSystemModule_ChainType(t *testing.T) {
api := newMockSystemAPI()

sys := NewSystemModule(nil, api, nil, nil, nil)
sys := NewSystemModule(nil, api, nil, nil, nil, nil)

res := new(string)
sys.ChainType(nil, nil, res)
require.Equal(t, testGenesisData.ChainType, *res)
}
func TestSystemModule_Name(t *testing.T) {
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil)
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil, nil)

res := new(string)
err := sys.Name(nil, nil, res)
Expand All @@ -192,7 +193,7 @@ func TestSystemModule_Name(t *testing.T) {
}

func TestSystemModule_Version(t *testing.T) {
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil)
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil, nil)

res := new(string)
err := sys.Version(nil, nil, res)
Expand All @@ -201,7 +202,7 @@ func TestSystemModule_Version(t *testing.T) {
}

func TestSystemModule_Properties(t *testing.T) {
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil)
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil, nil)

expected := map[string]interface{}(nil)

Expand Down Expand Up @@ -318,7 +319,7 @@ func setupSystemModule(t *testing.T) *SystemModule {
core := newCoreService(t, chain)
// TODO (ed) add transactions to txQueue and add test for those
txQueue := state.NewTransactionState()
return NewSystemModule(net, nil, core, chain.Storage, txQueue)
return NewSystemModule(net, nil, core, chain.Storage, txQueue, nil)
}

func newCoreService(t *testing.T, srvc *state.Service) *core.Service {
Expand Down Expand Up @@ -356,6 +357,41 @@ func newCoreService(t *testing.T, srvc *state.Service) *core.Service {
return core.NewTestService(t, cfg)
}

func TestSyncState(t *testing.T) {
fakeCommonHash := common.NewHash([]byte("fake"))
fakeHeader := &types.Header{
Number: big.NewInt(int64(49)),
}

blockapiMock := new(mocks.MockBlockAPI)
blockapiMock.On("BestBlockHash").Return(fakeCommonHash)
blockapiMock.On("GetHeader", fakeCommonHash).Return(fakeHeader, nil).Once()

netapiMock := new(mocks.MockNetworkAPI)
netapiMock.On("HighestBlock").Return(int64(90))
netapiMock.On("StartingBlock").Return(int64(10))

sysmodule := new(SystemModule)
sysmodule.blockAPI = blockapiMock
sysmodule.networkAPI = netapiMock

var res SyncStateResponse
err := sysmodule.SyncState(nil, nil, &res)
require.NoError(t, err)

expectedSyncState := SyncStateResponse{
CurrentBlock: uint32(49),
HighestBlock: uint32(90),
StartingBlock: uint32(10),
}

require.Equal(t, expectedSyncState, res)

blockapiMock.On("GetHeader", fakeCommonHash).Return(nil, errors.New("Problems while getting header")).Once()
err = sysmodule.SyncState(nil, nil, nil)
require.Error(t, err)
}

func TestLocalListenAddresses(t *testing.T) {
ma, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/7001/p2p/12D3KooWCYyh5xoAc5oRyiGU4d9ktcqFQ23JjitNFR6bEcbw7YdN")
require.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions dot/rpc/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ func TestNewService(t *testing.T) {
}

func TestService_Methods(t *testing.T) {
qtySystemMethods := 12
qtySystemMethods := 13
qtyRPCMethods := 1
qtyAuthorMethods := 7

rpcService := NewService()
sysMod := modules.NewSystemModule(nil, nil, nil, nil, nil)
sysMod := modules.NewSystemModule(nil, nil, nil, nil, nil, nil)
rpcService.BuildMethodNames(sysMod, "system")
m := rpcService.Methods()
require.Equal(t, qtySystemMethods, len(m)) // check to confirm quantity for methods is correct
Expand Down