Skip to content

Commit 5c8446e

Browse files
authored
chore(lib/runtime): refactor version struct and codec (#2673)
- Single `Version` struct - Encoding the `Version` always encode all the last fields - Decoding the version data to `Version` sets possible absent fields as zero if not in the data (`transaction_version`) - Remove `LegacyVersionData` struct, `Version` interface, getter methods, cloned structs for codec - Move decoding logic from `lib/runtime/wasmer/exports.go` to `lib/runtime/version.go` in `DecodeVersion` function - Use struct value for `Version` instead of its pointer (no reason to use a pointer) - Test code - Refactor multiple `TestInstance_Version*` in one test with test cases - Add runtime API items as expected fields in tests - Remove version runtime mockery mock - Simplify testing in other packages since we no longer need to use a test-only exported constructor `NewVersionData`
1 parent 8b0f6f0 commit 5c8446e

23 files changed

+575
-793
lines changed

dot/core/messages_integration_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ func createExtrinsic(t *testing.T, rt runtime.Instance, genHash common.Hash, non
5353
Era: ctypes.ExtrinsicEra{IsImmortalEra: false},
5454
GenesisHash: ctypes.Hash(genHash),
5555
Nonce: ctypes.NewUCompactFromUInt(nonce),
56-
SpecVersion: ctypes.U32(rv.SpecVersion()),
56+
SpecVersion: ctypes.U32(rv.SpecVersion),
5757
Tip: ctypes.NewUCompactFromUInt(0),
58-
TransactionVersion: ctypes.U32(rv.TransactionVersion()),
58+
TransactionVersion: ctypes.U32(rv.TransactionVersion),
5959
}
6060

6161
// Sign the transaction using Alice's key

dot/core/service.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,26 +454,27 @@ func (s *Service) DecodeSessionKeys(enc []byte) ([]byte, error) {
454454
}
455455

456456
// GetRuntimeVersion gets the current RuntimeVersion
457-
func (s *Service) GetRuntimeVersion(bhash *common.Hash) (runtime.Version, error) {
457+
func (s *Service) GetRuntimeVersion(bhash *common.Hash) (
458+
version runtime.Version, err error) {
458459
var stateRootHash *common.Hash
459460

460461
// If block hash is not nil then fetch the state root corresponding to the block.
461462
if bhash != nil {
462463
var err error
463464
stateRootHash, err = s.storageState.GetStateRootFromBlock(bhash)
464465
if err != nil {
465-
return nil, err
466+
return version, err
466467
}
467468
}
468469

469470
ts, err := s.storageState.TrieState(stateRootHash)
470471
if err != nil {
471-
return nil, err
472+
return version, err
472473
}
473474

474475
rt, err := s.blockState.GetRuntime(bhash)
475476
if err != nil {
476-
return nil, err
477+
return version, err
477478
}
478479

479480
rt.SetContextStorage(ts)

dot/core/service_integration_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ func TestService_HandleRuntimeChanges(t *testing.T) {
580580
v, err := rt.Version()
581581
require.NoError(t, err)
582582

583-
currSpecVersion := v.SpecVersion() // genesis runtime version.
583+
currSpecVersion := v.SpecVersion // genesis runtime version.
584584
hash := s.blockState.BestBlockHash() // genesisHash
585585

586586
digest := types.NewDigest()
@@ -615,7 +615,7 @@ func TestService_HandleRuntimeChanges(t *testing.T) {
615615

616616
v, err = parentRt.Version()
617617
require.NoError(t, err)
618-
require.Equal(t, v.SpecVersion(), currSpecVersion)
618+
require.Equal(t, v.SpecVersion, currSpecVersion)
619619

620620
bhash1 := newBlock1.Header.Hash()
621621
err = s.blockState.HandleRuntimeChanges(ts, parentRt, bhash1)
@@ -637,14 +637,14 @@ func TestService_HandleRuntimeChanges(t *testing.T) {
637637

638638
v, err = rt.Version()
639639
require.NoError(t, err)
640-
require.Equal(t, v.SpecVersion(), currSpecVersion)
640+
require.Equal(t, v.SpecVersion, currSpecVersion)
641641

642642
rt, err = s.blockState.GetRuntime(&rtUpdateBhash)
643643
require.NoError(t, err)
644644

645645
v, err = rt.Version()
646646
require.NoError(t, err)
647-
require.Equal(t, v.SpecVersion(), updatedSpecVersion)
647+
require.Equal(t, v.SpecVersion, updatedSpecVersion)
648648
}
649649

650650
func TestService_HandleCodeSubstitutes(t *testing.T) {

dot/core/service_test.go

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage"
2424
"github.com/ChainSafe/gossamer/lib/runtime/wasmer"
2525
"github.com/ChainSafe/gossamer/lib/transaction"
26+
"github.com/ChainSafe/gossamer/lib/trie"
2627
"github.com/ChainSafe/gossamer/pkg/scale"
2728
cscale "github.com/centrifuge/go-substrate-rpc-client/v4/scale"
2829
"github.com/centrifuge/go-substrate-rpc-client/v4/signature"
@@ -61,19 +62,18 @@ func generateExtrinsic(t *testing.T) (extrinsic, externalExtrinsic types.Extrins
6162
t.Helper()
6263
meta := generateTestCentrifugeMetadata(t)
6364

64-
testAPIItem := runtime.APIItem{
65-
Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
66-
Ver: 99,
65+
rv := runtime.Version{
66+
SpecName: []byte("polkadot"),
67+
ImplName: []byte("parity-polkadot"),
68+
AuthoringVersion: authoringVersion,
69+
SpecVersion: specVersion,
70+
ImplVersion: implVersion,
71+
APIItems: []runtime.APIItem{{
72+
Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
73+
Ver: 99,
74+
}},
75+
TransactionVersion: transactionVersion,
6776
}
68-
rv := runtime.NewVersionData(
69-
[]byte("polkadot"),
70-
[]byte("parity-polkadot"),
71-
authoringVersion,
72-
specVersion,
73-
implVersion,
74-
[]runtime.APIItem{testAPIItem},
75-
transactionVersion,
76-
)
7777

7878
keyring, err := keystore.NewSr25519Keyring()
7979
require.NoError(t, err)
@@ -95,9 +95,9 @@ func generateExtrinsic(t *testing.T) (extrinsic, externalExtrinsic types.Extrins
9595
Era: ctypes.ExtrinsicEra{IsImmortalEra: true},
9696
GenesisHash: testGenHash,
9797
Nonce: ctypes.NewUCompactFromUInt(uint64(0)),
98-
SpecVersion: ctypes.U32(rv.SpecVersion()),
98+
SpecVersion: ctypes.U32(rv.SpecVersion),
9999
Tip: ctypes.NewUCompactFromUInt(0),
100-
TransactionVersion: ctypes.U32(rv.TransactionVersion()),
100+
TransactionVersion: ctypes.U32(rv.TransactionVersion),
101101
}
102102

103103
// Sign the transaction using Alice's default account
@@ -1008,21 +1008,20 @@ func TestService_DecodeSessionKeys(t *testing.T) {
10081008

10091009
func TestServiceGetRuntimeVersion(t *testing.T) {
10101010
t.Parallel()
1011-
testAPIItem := runtime.APIItem{
1012-
Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
1013-
Ver: 99,
1011+
rv := runtime.Version{
1012+
SpecName: []byte("polkadot"),
1013+
ImplName: []byte("parity-polkadot"),
1014+
AuthoringVersion: authoringVersion,
1015+
SpecVersion: specVersion,
1016+
ImplVersion: implVersion,
1017+
APIItems: []runtime.APIItem{{
1018+
Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
1019+
Ver: 99,
1020+
}},
1021+
TransactionVersion: transactionVersion,
10141022
}
1015-
rv := runtime.NewVersionData(
1016-
[]byte("polkadot"),
1017-
[]byte("parity-polkadot"),
1018-
authoringVersion,
1019-
specVersion,
1020-
implVersion,
1021-
[]runtime.APIItem{testAPIItem},
1022-
transactionVersion,
1023-
)
1024-
1025-
ts := rtstorage.NewTrieState(nil)
1023+
emptyTrie := trie.NewEmptyTrie()
1024+
ts := rtstorage.NewTrieState(emptyTrie)
10261025

10271026
execTest := func(t *testing.T, s *Service, bhash *common.Hash, exp runtime.Version, expErr error) {
10281027
res, err := s.GetRuntimeVersion(bhash)
@@ -1041,7 +1040,7 @@ func TestServiceGetRuntimeVersion(t *testing.T) {
10411040
service := &Service{
10421041
storageState: mockStorageState,
10431042
}
1044-
execTest(t, service, &common.Hash{}, nil, errDummyErr)
1043+
execTest(t, service, &common.Hash{}, runtime.Version{}, errDummyErr)
10451044
})
10461045

10471046
t.Run("trie state err", func(t *testing.T) {
@@ -1053,7 +1052,7 @@ func TestServiceGetRuntimeVersion(t *testing.T) {
10531052
service := &Service{
10541053
storageState: mockStorageState,
10551054
}
1056-
execTest(t, service, &common.Hash{}, nil, errDummyErr)
1055+
execTest(t, service, &common.Hash{}, runtime.Version{}, errDummyErr)
10571056
})
10581057

10591058
t.Run("get runtime err", func(t *testing.T) {
@@ -1069,7 +1068,7 @@ func TestServiceGetRuntimeVersion(t *testing.T) {
10691068
storageState: mockStorageState,
10701069
blockState: mockBlockState,
10711070
}
1072-
execTest(t, service, &common.Hash{}, nil, errDummyErr)
1071+
execTest(t, service, &common.Hash{}, runtime.Version{}, errDummyErr)
10731072
})
10741073

10751074
t.Run("happy path", func(t *testing.T) {

dot/rpc/modules/api_mocks.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
modulesmocks "github.com/ChainSafe/gossamer/dot/rpc/modules/mocks"
88
"github.com/ChainSafe/gossamer/dot/types"
99
"github.com/ChainSafe/gossamer/lib/common"
10-
runtimemocks "github.com/ChainSafe/gossamer/lib/runtime/mocks"
10+
"github.com/ChainSafe/gossamer/lib/runtime"
1111
"github.com/ChainSafe/gossamer/lib/transaction"
1212
"github.com/stretchr/testify/mock"
1313
)
@@ -63,22 +63,10 @@ func NewMockCoreAPI() *modulesmocks.CoreAPI {
6363
m := new(modulesmocks.CoreAPI)
6464
m.On("InsertKey", mock.AnythingOfType("crypto.Keypair"), mock.AnythingOfType("string")).Return(nil)
6565
m.On("HasKey", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(false, nil)
66-
m.On("GetRuntimeVersion", mock.AnythingOfType("*common.Hash")).Return(NewMockVersion(), nil)
66+
m.On("GetRuntimeVersion", mock.AnythingOfType("*common.Hash")).
67+
Return(runtime.Version{SpecName: []byte(`mock-spec`)}, nil)
6768
m.On("IsBlockProducer").Return(false)
6869
m.On("HandleSubmittedExtrinsic", mock.AnythingOfType("types.Extrinsic")).Return(nil)
6970
m.On("GetMetadata", mock.AnythingOfType("*common.Hash")).Return(nil, nil)
7071
return m
7172
}
72-
73-
// NewMockVersion creates and returns an runtime Version interface mock
74-
func NewMockVersion() *runtimemocks.Version {
75-
m := new(runtimemocks.Version)
76-
m.On("SpecName").Return([]byte(`mock-spec`))
77-
m.On("ImplName").Return(nil)
78-
m.On("AuthoringVersion").Return(uint32(0))
79-
m.On("SpecVersion").Return(uint32(0))
80-
m.On("ImplVersion").Return(uint32(0))
81-
m.On("TransactionVersion").Return(uint32(0))
82-
m.On("APIItems").Return(nil)
83-
return m
84-
}

dot/rpc/modules/mocks/core_api.go

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dot/rpc/modules/state.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,13 @@ func (sm *StateModule) GetRuntimeVersion(
304304
return err
305305
}
306306

307-
res.SpecName = string(rtVersion.SpecName())
308-
res.ImplName = string(rtVersion.ImplName())
309-
res.AuthoringVersion = rtVersion.AuthoringVersion()
310-
res.SpecVersion = rtVersion.SpecVersion()
311-
res.ImplVersion = rtVersion.ImplVersion()
312-
res.TransactionVersion = rtVersion.TransactionVersion()
313-
res.Apis = ConvertAPIs(rtVersion.APIItems())
307+
res.SpecName = string(rtVersion.SpecName)
308+
res.ImplName = string(rtVersion.ImplName)
309+
res.AuthoringVersion = rtVersion.AuthoringVersion
310+
res.SpecVersion = rtVersion.SpecVersion
311+
res.ImplVersion = rtVersion.ImplVersion
312+
res.TransactionVersion = rtVersion.TransactionVersion
313+
res.Apis = ConvertAPIs(rtVersion.APIItems)
314314

315315
return nil
316316
}

dot/rpc/modules/state_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -448,25 +448,25 @@ func TestStateModuleGetReadProof(t *testing.T) {
448448

449449
func TestStateModuleGetRuntimeVersion(t *testing.T) {
450450
hash := common.MustHexToHash("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a")
451-
testAPIItem := runtime.APIItem{
452-
Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
453-
Ver: 99,
451+
version := runtime.Version{
452+
SpecName: []byte("polkadot"),
453+
ImplName: []byte("parity-polkadot"),
454+
AuthoringVersion: 0,
455+
SpecVersion: 25,
456+
ImplVersion: 0,
457+
APIItems: []runtime.APIItem{{
458+
Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
459+
Ver: 99,
460+
}},
461+
TransactionVersion: 5,
454462
}
455-
version := runtime.NewVersionData(
456-
[]byte("polkadot"),
457-
[]byte("parity-polkadot"),
458-
0,
459-
25,
460-
0,
461-
[]runtime.APIItem{testAPIItem},
462-
5,
463-
)
464463

465464
mockCoreAPI := new(mocks.CoreAPI)
466465
mockCoreAPI.On("GetRuntimeVersion", &hash).Return(version, nil)
467466

468467
mockCoreAPIErr := new(mocks.CoreAPI)
469-
mockCoreAPIErr.On("GetRuntimeVersion", &hash).Return(nil, errors.New("GetRuntimeVersion Error"))
468+
mockCoreAPIErr.On("GetRuntimeVersion", &hash).
469+
Return(runtime.Version{}, errors.New("GetRuntimeVersion Error"))
470470

471471
type fields struct {
472472
networkAPI NetworkAPI

dot/rpc/subscription/listeners.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -410,13 +410,13 @@ func (l *RuntimeVersionListener) Listen() {
410410
return
411411
}
412412
ver := modules.StateRuntimeVersionResponse{}
413-
ver.SpecName = string(rtVersion.SpecName())
414-
ver.ImplName = string(rtVersion.ImplName())
415-
ver.AuthoringVersion = rtVersion.AuthoringVersion()
416-
ver.SpecVersion = rtVersion.SpecVersion()
417-
ver.ImplVersion = rtVersion.ImplVersion()
418-
ver.TransactionVersion = rtVersion.TransactionVersion()
419-
ver.Apis = modules.ConvertAPIs(rtVersion.APIItems())
413+
ver.SpecName = string(rtVersion.SpecName)
414+
ver.ImplName = string(rtVersion.ImplName)
415+
ver.AuthoringVersion = rtVersion.AuthoringVersion
416+
ver.SpecVersion = rtVersion.SpecVersion
417+
ver.ImplVersion = rtVersion.ImplVersion
418+
ver.TransactionVersion = rtVersion.TransactionVersion
419+
ver.Apis = modules.ConvertAPIs(rtVersion.APIItems)
420420

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

@@ -430,13 +430,13 @@ func (l *RuntimeVersionListener) Listen() {
430430

431431
ver := modules.StateRuntimeVersionResponse{}
432432

433-
ver.SpecName = string(info.SpecName())
434-
ver.ImplName = string(info.ImplName())
435-
ver.AuthoringVersion = info.AuthoringVersion()
436-
ver.SpecVersion = info.SpecVersion()
437-
ver.ImplVersion = info.ImplVersion()
438-
ver.TransactionVersion = info.TransactionVersion()
439-
ver.Apis = modules.ConvertAPIs(info.APIItems())
433+
ver.SpecName = string(info.SpecName)
434+
ver.ImplName = string(info.ImplName)
435+
ver.AuthoringVersion = info.AuthoringVersion
436+
ver.SpecVersion = info.SpecVersion
437+
ver.ImplVersion = info.ImplVersion
438+
ver.TransactionVersion = info.TransactionVersion
439+
ver.Apis = modules.ConvertAPIs(info.APIItems)
440440

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

dot/rpc/subscription/listeners_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ func TestRuntimeChannelListener_Listen(t *testing.T) {
365365
SpecVersion: 25,
366366
ImplVersion: 0,
367367
TransactionVersion: 5,
368-
Apis: modules.ConvertAPIs(version.APIItems()),
368+
Apis: modules.ConvertAPIs(version.APIItems),
369369
}
370370

371371
expectedUpdateResponse := newSubcriptionBaseResponseJSON()

dot/state/block.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,15 +598,15 @@ func (bs *BlockState) HandleRuntimeChanges(newState *rtstorage.TrieState,
598598

599599
// only update runtime during code substitution if runtime SpecVersion is updated
600600
previousVersion, _ := rt.Version()
601-
if previousVersion.SpecVersion() == newVersion.SpecVersion() {
601+
if previousVersion.SpecVersion == newVersion.SpecVersion {
602602
logger.Info("not upgrading runtime code during code substitution")
603603
bs.StoreRuntime(bHash, rt)
604604
return nil
605605
}
606606

607607
logger.Infof(
608608
"🔄 detected runtime code change, upgrading with block %s from previous code hash %s and spec %d to new code hash %s and spec %d...", //nolint:lll
609-
bHash, codeHash, previousVersion.SpecVersion(), currCodeHash, newVersion.SpecVersion())
609+
bHash, codeHash, previousVersion.SpecVersion, currCodeHash, newVersion.SpecVersion)
610610
}
611611

612612
rtCfg := wasmer.Config{

0 commit comments

Comments
 (0)