Skip to content

Commit

Permalink
feat(dot/rpc) Add system_syncState rpc call (ChainSafe#1691)
Browse files Browse the repository at this point in the history
* chore: adjust tests

* chore: exposing network methods

* chore: add test

* chore: resolve lint and improve func description

* chore: resolve lint
  • Loading branch information
EclesioMeloJunior committed Jul 19, 2021
1 parent 093e149 commit a3786e9
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 14 deletions.
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 {
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

0 comments on commit a3786e9

Please sign in to comment.