Skip to content

Commit a3786e9

Browse files
feat(dot/rpc) Add system_syncState rpc call (#1691)
* chore: adjust tests * chore: exposing network methods * chore: add test * chore: resolve lint and improve func description * chore: resolve lint
1 parent 093e149 commit a3786e9

File tree

7 files changed

+114
-14
lines changed

7 files changed

+114
-14
lines changed

dot/network/service.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,3 +691,13 @@ func (s *Service) Peers() []common.PeerInfo {
691691
func (s *Service) NodeRoles() byte {
692692
return s.cfg.Roles
693693
}
694+
695+
// HighestBlock returns the highest known block number
696+
func (s *Service) HighestBlock() int64 {
697+
return s.syncQueue.goal
698+
}
699+
700+
// StartingBlock return the starting block number that's currently being synced
701+
func (s *Service) StartingBlock() int64 {
702+
return s.syncQueue.currStart
703+
}

dot/rpc/http.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func (h *HTTPServer) RegisterModules(mods []string) {
9595
switch mod {
9696
case "system":
9797
srvc = modules.NewSystemModule(h.serverConfig.NetworkAPI, h.serverConfig.SystemAPI,
98-
h.serverConfig.CoreAPI, h.serverConfig.StorageAPI, h.serverConfig.TransactionQueueAPI)
98+
h.serverConfig.CoreAPI, h.serverConfig.StorageAPI, h.serverConfig.TransactionQueueAPI, h.serverConfig.BlockAPI)
9999
case "author":
100100
srvc = modules.NewAuthorModule(h.logger, h.serverConfig.CoreAPI, h.serverConfig.RuntimeAPI, h.serverConfig.TransactionQueueAPI)
101101
case "chain":

dot/rpc/modules/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ type NetworkAPI interface {
4949
Stop() error
5050
Start() error
5151
IsStopped() bool
52+
HighestBlock() int64
53+
StartingBlock() int64
5254
}
5355

5456
// BlockProducerAPI is the interface for BlockProducer methods

dot/rpc/modules/mocks/network_api.go

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dot/rpc/modules/system.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type SystemModule struct {
3636
coreAPI CoreAPI
3737
storageAPI StorageAPI
3838
txStateAPI TransactionStateAPI
39+
blockAPI BlockAPI
3940
}
4041

4142
// EmptyRequest represents an RPC request with no fields
@@ -69,15 +70,23 @@ type StringRequest struct {
6970
String string
7071
}
7172

73+
// SyncStateResponse is the struct to return on the system_syncState rpc call
74+
type SyncStateResponse struct {
75+
CurrentBlock uint32 `json:"currentBlock"`
76+
HighestBlock uint32 `json:"highestBlock"`
77+
StartingBlock uint32 `json:"startingBlock"`
78+
}
79+
7280
// NewSystemModule creates a new API instance
7381
func NewSystemModule(net NetworkAPI, sys SystemAPI, core CoreAPI,
74-
storage StorageAPI, txAPI TransactionStateAPI) *SystemModule {
82+
storage StorageAPI, txAPI TransactionStateAPI, blockAPI BlockAPI) *SystemModule {
7583
return &SystemModule{
7684
networkAPI: net, // TODO: migrate to network state
7785
systemAPI: sys,
7886
coreAPI: core,
7987
storageAPI: storage,
8088
txStateAPI: txAPI,
89+
blockAPI: blockAPI,
8190
}
8291
}
8392

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

240+
// SyncState Returns the state of the syncing of the node.
241+
func (sm *SystemModule) SyncState(r *http.Request, req *EmptyRequest, res *SyncStateResponse) error {
242+
h, err := sm.blockAPI.GetHeader(sm.blockAPI.BestBlockHash())
243+
if err != nil {
244+
return err
245+
}
246+
247+
*res = SyncStateResponse{
248+
CurrentBlock: uint32(h.Number.Int64()),
249+
HighestBlock: uint32(sm.networkAPI.HighestBlock()),
250+
StartingBlock: uint32(sm.networkAPI.StartingBlock()),
251+
}
252+
return nil
253+
}
254+
231255
// LocalListenAddresses Returns the libp2p multiaddresses that the local node is listening on
232256
func (sm *SystemModule) LocalListenAddresses(r *http.Request, req *EmptyRequest, res *[]string) error {
233257
netstate := sm.networkAPI.NetworkState()

dot/rpc/modules/system_test.go

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package modules
1818

1919
import (
20+
"errors"
2021
"fmt"
2122
"math/big"
2223
"os"
@@ -89,7 +90,7 @@ func newNetworkService(t *testing.T) *network.Service {
8990
func TestSystemModule_Health(t *testing.T) {
9091
net := newNetworkService(t)
9192
net.Stop()
92-
sys := NewSystemModule(net, nil, nil, nil, nil)
93+
sys := NewSystemModule(net, nil, nil, nil, nil, nil)
9394

9495
res := &SystemHealthResponse{}
9596
err := sys.Health(nil, nil, res)
@@ -103,7 +104,7 @@ func TestSystemModule_Health(t *testing.T) {
103104
// Test RPC's System.NetworkState() response
104105
func TestSystemModule_NetworkState(t *testing.T) {
105106
net := newNetworkService(t)
106-
sys := NewSystemModule(net, nil, nil, nil, nil)
107+
sys := NewSystemModule(net, nil, nil, nil, nil, nil)
107108

108109
res := &SystemNetworkStateResponse{}
109110
err := sys.NetworkState(nil, nil, res)
@@ -120,7 +121,7 @@ func TestSystemModule_NetworkState(t *testing.T) {
120121
func TestSystemModule_Peers(t *testing.T) {
121122
net := newNetworkService(t)
122123
net.Stop()
123-
sys := NewSystemModule(net, nil, nil, nil, nil)
124+
sys := NewSystemModule(net, nil, nil, nil, nil, nil)
124125

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

134135
func TestSystemModule_NodeRoles(t *testing.T) {
135136
net := newNetworkService(t)
136-
sys := NewSystemModule(net, nil, nil, nil, nil)
137+
sys := NewSystemModule(net, nil, nil, nil, nil, nil)
137138
expected := []interface{}{"Full"}
138139

139140
var res []interface{}
@@ -165,7 +166,7 @@ func newMockSystemAPI() *mocks.MockSystemAPI {
165166
}
166167

167168
func TestSystemModule_Chain(t *testing.T) {
168-
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil)
169+
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil, nil)
169170

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

179-
sys := NewSystemModule(nil, api, nil, nil, nil)
180+
sys := NewSystemModule(nil, api, nil, nil, nil, nil)
180181

181182
res := new(string)
182183
sys.ChainType(nil, nil, res)
183184
require.Equal(t, testGenesisData.ChainType, *res)
184185
}
185186
func TestSystemModule_Name(t *testing.T) {
186-
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil)
187+
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil, nil)
187188

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

194195
func TestSystemModule_Version(t *testing.T) {
195-
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil)
196+
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil, nil)
196197

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

203204
func TestSystemModule_Properties(t *testing.T) {
204-
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil)
205+
sys := NewSystemModule(nil, newMockSystemAPI(), nil, nil, nil, nil)
205206

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

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

324325
func newCoreService(t *testing.T, srvc *state.Service) *core.Service {
@@ -356,6 +357,41 @@ func newCoreService(t *testing.T, srvc *state.Service) *core.Service {
356357
return core.NewTestService(t, cfg)
357358
}
358359

360+
func TestSyncState(t *testing.T) {
361+
fakeCommonHash := common.NewHash([]byte("fake"))
362+
fakeHeader := &types.Header{
363+
Number: big.NewInt(int64(49)),
364+
}
365+
366+
blockapiMock := new(mocks.MockBlockAPI)
367+
blockapiMock.On("BestBlockHash").Return(fakeCommonHash)
368+
blockapiMock.On("GetHeader", fakeCommonHash).Return(fakeHeader, nil).Once()
369+
370+
netapiMock := new(mocks.MockNetworkAPI)
371+
netapiMock.On("HighestBlock").Return(int64(90))
372+
netapiMock.On("StartingBlock").Return(int64(10))
373+
374+
sysmodule := new(SystemModule)
375+
sysmodule.blockAPI = blockapiMock
376+
sysmodule.networkAPI = netapiMock
377+
378+
var res SyncStateResponse
379+
err := sysmodule.SyncState(nil, nil, &res)
380+
require.NoError(t, err)
381+
382+
expectedSyncState := SyncStateResponse{
383+
CurrentBlock: uint32(49),
384+
HighestBlock: uint32(90),
385+
StartingBlock: uint32(10),
386+
}
387+
388+
require.Equal(t, expectedSyncState, res)
389+
390+
blockapiMock.On("GetHeader", fakeCommonHash).Return(nil, errors.New("Problems while getting header")).Once()
391+
err = sysmodule.SyncState(nil, nil, nil)
392+
require.Error(t, err)
393+
}
394+
359395
func TestLocalListenAddresses(t *testing.T) {
360396
ma, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/7001/p2p/12D3KooWCYyh5xoAc5oRyiGU4d9ktcqFQ23JjitNFR6bEcbw7YdN")
361397
require.NoError(t, err)

dot/rpc/service_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ func TestNewService(t *testing.T) {
3333
}
3434

3535
func TestService_Methods(t *testing.T) {
36-
qtySystemMethods := 12
36+
qtySystemMethods := 13
3737
qtyRPCMethods := 1
3838
qtyAuthorMethods := 7
3939

4040
rpcService := NewService()
41-
sysMod := modules.NewSystemModule(nil, nil, nil, nil, nil)
41+
sysMod := modules.NewSystemModule(nil, nil, nil, nil, nil, nil)
4242
rpcService.BuildMethodNames(sysMod, "system")
4343
m := rpcService.Methods()
4444
require.Equal(t, qtySystemMethods, len(m)) // check to confirm quantity for methods is correct

0 commit comments

Comments
 (0)