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

fix(rpc/subscription): subscribe runtime version notify when version changes #1686

Merged
merged 56 commits into from
Aug 13, 2021
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
7325277
add code for runtime version changed fix
edwardmack Jul 2, 2021
2d324de
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 7, 2021
9394d38
fix return type
edwardmack Jul 7, 2021
cfe9117
update mock in Makefile
edwardmack Jul 7, 2021
37c8878
fix core_api mock
EclesioMeloJunior Jul 8, 2021
fb75b48
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 8, 2021
feb5f4d
implement notifications for runtime updates
edwardmack Jul 8, 2021
a31474d
lint
edwardmack Jul 8, 2021
3017ed3
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 9, 2021
fd83528
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 9, 2021
432d604
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 9, 2021
0dcc08f
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 12, 2021
d7c5d59
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 14, 2021
8c16176
implement unregister runtime version listener
edwardmack Jul 14, 2021
de0c40b
make mocks and lint
edwardmack Jul 15, 2021
5512348
refactor runtime subscription name, change error handeling
edwardmack Jul 15, 2021
09c9b2e
remove unneeded select case
edwardmack Jul 15, 2021
cf0e477
lint, refactor GetID to GetChannelID
edwardmack Jul 15, 2021
6c3ea54
lint
edwardmack Jul 15, 2021
ade2a82
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 15, 2021
c0eb904
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 20, 2021
8031b82
add sync.WaitGroup to notify Runtime Updated
edwardmack Jul 21, 2021
d6f6cea
add test for Register UnRegister Runtime Update Channel
edwardmack Jul 21, 2021
2f6c7e2
add check for id
edwardmack Jul 21, 2021
98fb9d9
add register panic test
edwardmack Jul 21, 2021
42f436e
add test to produce panic
edwardmack Jul 21, 2021
125a5d1
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 21, 2021
0e2fcd7
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 22, 2021
7e7e9bd
generate id as uuid, add locks, delete from map
edwardmack Jul 23, 2021
66bd9e2
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 23, 2021
ff35489
update runtime updated channel ids to use uint32
edwardmack Jul 23, 2021
70d6c27
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 23, 2021
cecc811
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 27, 2021
c8d8d92
change logging to debug
edwardmack Jul 27, 2021
4747f96
remove comment
edwardmack Jul 27, 2021
c0cbdc0
move uuid into check loop
edwardmack Jul 27, 2021
b70b82c
update runtime test
edwardmack Jul 27, 2021
fcac2b5
add test for notify runtime updated
edwardmack Jul 27, 2021
a41d0af
update runtime tests
edwardmack Jul 27, 2021
568ed88
move runtime notify from coreAPI to blockStateAPI
edwardmack Jul 27, 2021
4fd52d8
fix mocks for tests
edwardmack Jul 27, 2021
5e7fba5
refactor state_test
edwardmack Jul 28, 2021
6038b6c
add tests
edwardmack Jul 29, 2021
ea37d63
lint
edwardmack Jul 29, 2021
dc78e71
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Jul 29, 2021
0de3c60
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Aug 4, 2021
739f8aa
remove commented code, fix var assignment
edwardmack Aug 4, 2021
e3e5cef
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Aug 4, 2021
39f4a88
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Aug 5, 2021
cb364a9
fix merge conflict
edwardmack Aug 5, 2021
84f89d3
add check if channel is ok
edwardmack Aug 5, 2021
1a877ac
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Aug 6, 2021
6270ede
update unit test
edwardmack Aug 6, 2021
9be6179
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Aug 9, 2021
a22fca9
send notification as go routine
edwardmack Aug 9, 2021
154061f
Merge branch 'development' into ed/fix_state_subscribeRuntimeVersion
edwardmack Aug 13, 2021
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
3 changes: 1 addition & 2 deletions dot/core/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"testing"
"time"

coremocks "github.com/ChainSafe/gossamer/dot/core/mocks"
"github.com/ChainSafe/gossamer/dot/network"
"github.com/ChainSafe/gossamer/dot/state"
"github.com/ChainSafe/gossamer/dot/sync"
Expand All @@ -37,8 +38,6 @@ import (
"github.com/ChainSafe/gossamer/lib/utils"
log "github.com/ChainSafe/log15"
"github.com/stretchr/testify/require"

coremocks "github.com/ChainSafe/gossamer/dot/core/mocks"
)

func addTestBlocksToState(t *testing.T, depth int, blockState BlockState) {
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 @@ -39,6 +39,8 @@ type BlockAPI interface {
RegisterFinalizedChannel(ch chan<- *types.FinalisationInfo) (byte, error)
UnregisterFinalisedChannel(id byte)
SubChain(start, end common.Hash) ([]common.Hash, error)
RegisterRuntimeUpdatedChannel(ch chan<- runtime.Version) (uint32, error)
UnregisterRuntimeUpdatedChannel(id uint32) bool
}

// NetworkAPI interface for network state methods
Expand Down
18 changes: 17 additions & 1 deletion dot/rpc/modules/api_mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package modules
import (
modulesmocks "github.com/ChainSafe/gossamer/dot/rpc/modules/mocks"
"github.com/ChainSafe/gossamer/lib/common"
runtimemocks "github.com/ChainSafe/gossamer/lib/runtime/mocks"
"github.com/stretchr/testify/mock"
)

Expand Down Expand Up @@ -35,6 +36,8 @@ func NewMockBlockAPI() *modulesmocks.BlockAPI {
m.On("GetJustification", mock.AnythingOfType("common.Hash")).Return(make([]byte, 10), nil)
m.On("HasJustification", mock.AnythingOfType("common.Hash")).Return(true, nil)
m.On("SubChain", mock.AnythingOfType("common.Hash"), mock.AnythingOfType("common.Hash")).Return(make([]common.Hash, 0), nil)
m.On("RegisterRuntimeUpdatedChannel", mock.AnythingOfType("chan<- runtime.Version")).Return(uint32(0), nil)

return m
}

Expand All @@ -43,9 +46,22 @@ func NewMockCoreAPI() *modulesmocks.MockCoreAPI {
m := new(modulesmocks.MockCoreAPI)
m.On("InsertKey", mock.AnythingOfType("crypto.Keypair"))
m.On("HasKey", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(false, nil)
m.On("GetRuntimeVersion", mock.AnythingOfType("*common.Hash")).Return(nil, nil)
m.On("GetRuntimeVersion", mock.AnythingOfType("*common.Hash")).Return(NewMockVersion(), nil)
m.On("IsBlockProducer").Return(false)
m.On("HandleSubmittedExtrinsic", mock.AnythingOfType("types.Extrinsic")).Return(nil)
m.On("GetMetadata", mock.AnythingOfType("*common.Hash")).Return(nil, nil)
return m
}

// NewMockVersion creates and returns an runtime Version interface mock
func NewMockVersion() *runtimemocks.MockVersion {
m := new(runtimemocks.MockVersion)
m.On("SpecName").Return([]byte(`mock-spec`))
m.On("ImplName").Return(nil)
m.On("AuthoringVersion").Return(uint32(0))
m.On("SpecVersion").Return(uint32(0))
m.On("ImplVersion").Return(uint32(0))
m.On("TransactionVersion").Return(uint32(0))
m.On("APIItems").Return(nil)
return m
}
43 changes: 43 additions & 0 deletions dot/rpc/modules/api_mocks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2019 ChainSafe Systems (ON) Corp.
// This file is part of gossamer.
//
// The gossamer library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The gossamer library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the gossamer library. If not, see <http://www.gnu.org/licenses/>.

package modules

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestNewMockStorageAPI(t *testing.T) {
m := NewMockStorageAPI()
require.NotNil(t, m)
}

func TestNewMockBlockAPI(t *testing.T) {
m := NewMockBlockAPI()
require.NotNil(t, m)
}

func TestNewMockCoreAPI(t *testing.T) {
m := NewMockCoreAPI()
require.NotNil(t, m)
}

func TestNewMockVersion(t *testing.T) {
m := NewMockVersion()
require.NotNil(t, m)
}
37 changes: 37 additions & 0 deletions dot/rpc/modules/mocks/BlockAPI.go

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

14 changes: 0 additions & 14 deletions dot/rpc/modules/mocks/core_api.go

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

46 changes: 40 additions & 6 deletions dot/rpc/subscription/listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/ChainSafe/gossamer/dot/state"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/runtime"
)

const (
Expand Down Expand Up @@ -282,20 +283,26 @@ func (l *ExtrinsicSubmitListener) Stop() error {

// RuntimeVersionListener to handle listening for Runtime Version
type RuntimeVersionListener struct {
wsconn *WSConn
subID uint32
wsconn WSConnAPI
subID uint32
runtimeUpdate chan runtime.Version
channelID uint32
coreAPI modules.CoreAPI
}

// VersionListener interface defining methods that version listener must implement
type VersionListener interface {
GetChannelID() uint32
}

// Listen implementation of Listen interface to listen for runtime version changes
func (l *RuntimeVersionListener) Listen() {
// This sends current runtime version once when subscription is created
// TODO (ed) add logic to send updates when runtime version changes
rtVersion, err := l.wsconn.CoreAPI.GetRuntimeVersion(nil)
rtVersion, err := l.coreAPI.GetRuntimeVersion(nil)
if err != nil {
return
}
ver := modules.StateRuntimeVersionResponse{}

ver.SpecName = string(rtVersion.SpecName())
ver.ImplName = string(rtVersion.ImplName())
ver.AuthoringVersion = rtVersion.AuthoringVersion()
Expand All @@ -304,7 +311,34 @@ func (l *RuntimeVersionListener) Listen() {
ver.TransactionVersion = rtVersion.TransactionVersion()
ver.Apis = modules.ConvertAPIs(rtVersion.APIItems())

l.wsconn.safeSend(newSubscriptionResponse(stateRuntimeVersionMethod, l.subID, ver))
go l.wsconn.safeSend(newSubscriptionResponse(stateRuntimeVersionMethod, l.subID, ver))

// listen for runtime updates
go func() {
for {
info, ok := <-l.runtimeUpdate
if !ok {
return
}

ver := modules.StateRuntimeVersionResponse{}

ver.SpecName = string(info.SpecName())
ver.ImplName = string(info.ImplName())
ver.AuthoringVersion = info.AuthoringVersion()
ver.SpecVersion = info.SpecVersion()
ver.ImplVersion = info.ImplVersion()
ver.TransactionVersion = info.TransactionVersion()
ver.Apis = modules.ConvertAPIs(info.APIItems())

l.wsconn.safeSend(newSubscriptionResponse(stateRuntimeVersionMethod, l.subID, ver))
}
}()
}

// GetChannelID function that returns listener's channel ID
func (l *RuntimeVersionListener) GetChannelID() uint32 {
return l.channelID
}

// Stop to runtimeVersionListener not implemented yet because the listener
Expand Down
59 changes: 59 additions & 0 deletions dot/rpc/subscription/listeners_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ package subscription
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"math/big"
"net/http"
"net/http/httptest"
"path/filepath"
"strings"
"testing"
"time"
Expand All @@ -33,6 +35,8 @@ import (
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/grandpa"
"github.com/ChainSafe/gossamer/lib/runtime"
"github.com/ChainSafe/gossamer/lib/runtime/wasmer"
"github.com/gorilla/websocket"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -325,3 +329,58 @@ func setupWSConn(t *testing.T) (*WSConn, *websocket.Conn, func()) {

return wskt, ws, cancel
}

func TestRuntimeChannelListener_Listen(t *testing.T) {
notifyChan := make(chan runtime.Version)
mockConnection := &MockWSConnAPI{}
rvl := RuntimeVersionListener{
wsconn: mockConnection,
subID: 0,
runtimeUpdate: notifyChan,
coreAPI: modules.NewMockCoreAPI(),
}

expectedInitialVersion := modules.StateRuntimeVersionResponse{
SpecName: "mock-spec",
Apis: modules.ConvertAPIs(nil),
}

expectedInitialResponse := newSubcriptionBaseResponseJSON()
expectedInitialResponse.Method = "state_runtimeVersion"
expectedInitialResponse.Params.Result = expectedInitialVersion

instance := wasmer.NewTestInstance(t, runtime.NODE_RUNTIME)
_, err := runtime.GetRuntimeBlob(runtime.POLKADOT_RUNTIME_FP, runtime.POLKADOT_RUNTIME_URL)
require.NoError(t, err)
fp, err := filepath.Abs(runtime.POLKADOT_RUNTIME_FP)
require.NoError(t, err)
code, err := ioutil.ReadFile(fp)
require.NoError(t, err)
version, err := instance.CheckRuntimeVersion(code)
require.NoError(t, err)

expectedUpdatedVersion := modules.StateRuntimeVersionResponse{
SpecName: "polkadot",
ImplName: "parity-polkadot",
AuthoringVersion: 0,
SpecVersion: 25,
ImplVersion: 0,
TransactionVersion: 5,
Apis: modules.ConvertAPIs(version.APIItems()),
}

expectedUpdateResponse := newSubcriptionBaseResponseJSON()
expectedUpdateResponse.Method = "state_runtimeVersion"
expectedUpdateResponse.Params.Result = expectedUpdatedVersion

go rvl.Listen()

//check initial response
time.Sleep(time.Millisecond * 10)
require.Equal(t, expectedInitialResponse, mockConnection.lastMessage)

// check response after update
notifyChan <- version
time.Sleep(time.Millisecond * 10)
require.Equal(t, expectedUpdateResponse, mockConnection.lastMessage)
}
2 changes: 2 additions & 0 deletions dot/rpc/subscription/subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ func (c *WSConn) getUnsubListener(method string, params interface{}) (unsubListe
switch method {
case "state_unsubscribeStorage":
unsub = c.unsubscribeStorageListener
case "state_unsubscribeRuntimeVersion":
unsub = c.unsubscribeRuntimeVersionListener
case "grandpa_unsubscribeJustifications":
unsub = c.unsubscribeGrandpaJustificationListener
default:
Expand Down
Loading