diff --git a/dot/core/messages_integration_test.go b/dot/core/messages_integration_test.go index c20d6453bea..88155ce91b2 100644 --- a/dot/core/messages_integration_test.go +++ b/dot/core/messages_integration_test.go @@ -53,9 +53,9 @@ func createExtrinsic(t *testing.T, rt runtime.Instance, genHash common.Hash, non Era: ctypes.ExtrinsicEra{IsImmortalEra: false}, GenesisHash: ctypes.Hash(genHash), Nonce: ctypes.NewUCompactFromUInt(nonce), - SpecVersion: ctypes.U32(rv.SpecVersion()), + SpecVersion: ctypes.U32(rv.GetSpecVersion()), Tip: ctypes.NewUCompactFromUInt(0), - TransactionVersion: ctypes.U32(rv.TransactionVersion()), + TransactionVersion: ctypes.U32(rv.GetTransactionVersion()), } // Sign the transaction using Alice's key diff --git a/dot/core/service_integration_test.go b/dot/core/service_integration_test.go index cbe534da096..8cfb98569d6 100644 --- a/dot/core/service_integration_test.go +++ b/dot/core/service_integration_test.go @@ -613,8 +613,8 @@ func TestService_HandleRuntimeChanges(t *testing.T) { v, err := rt.Version() require.NoError(t, err) - currSpecVersion := v.SpecVersion() // genesis runtime version. - hash := s.blockState.BestBlockHash() // genesisHash + currSpecVersion := v.GetSpecVersion() // genesis runtime version. + hash := s.blockState.BestBlockHash() // genesisHash digest := types.NewDigest() err = digest.Add(types.PreRuntimeDigest{ @@ -648,7 +648,7 @@ func TestService_HandleRuntimeChanges(t *testing.T) { v, err = parentRt.Version() require.NoError(t, err) - require.Equal(t, v.SpecVersion(), currSpecVersion) + require.Equal(t, v.GetSpecVersion(), currSpecVersion) bhash1 := newBlock1.Header.Hash() err = s.blockState.HandleRuntimeChanges(ts, parentRt, bhash1) @@ -670,14 +670,14 @@ func TestService_HandleRuntimeChanges(t *testing.T) { v, err = rt.Version() require.NoError(t, err) - require.Equal(t, v.SpecVersion(), currSpecVersion) + require.Equal(t, v.GetSpecVersion(), currSpecVersion) rt, err = s.blockState.GetRuntime(&rtUpdateBhash) require.NoError(t, err) v, err = rt.Version() require.NoError(t, err) - require.Equal(t, v.SpecVersion(), updatedSpecVersion) + require.Equal(t, v.GetSpecVersion(), updatedSpecVersion) } func TestService_HandleCodeSubstitutes(t *testing.T) { diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 8f2b847fcde..b4637f281b8 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -61,19 +61,18 @@ func generateExtrinsic(t *testing.T) (extrinsic, externalExtrinsic types.Extrins t.Helper() meta := generateTestCentrifugeMetadata(t) - testAPIItem := runtime.APIItem{ - Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, - Ver: 99, + rv := runtime.VersionData{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, + Ver: 99, + }}, + TransactionVersion: transactionVersion, } - rv := runtime.NewVersionData( - []byte("polkadot"), - []byte("parity-polkadot"), - authoringVersion, - specVersion, - implVersion, - []runtime.APIItem{testAPIItem}, - transactionVersion, - ) keyring, err := keystore.NewSr25519Keyring() require.NoError(t, err) @@ -95,9 +94,9 @@ func generateExtrinsic(t *testing.T) (extrinsic, externalExtrinsic types.Extrins Era: ctypes.ExtrinsicEra{IsImmortalEra: true}, GenesisHash: testGenHash, Nonce: ctypes.NewUCompactFromUInt(uint64(0)), - SpecVersion: ctypes.U32(rv.SpecVersion()), + SpecVersion: ctypes.U32(rv.GetSpecVersion()), Tip: ctypes.NewUCompactFromUInt(0), - TransactionVersion: ctypes.U32(rv.TransactionVersion()), + TransactionVersion: ctypes.U32(rv.GetTransactionVersion()), } // Sign the transaction using Alice's default account @@ -961,19 +960,18 @@ func TestService_DecodeSessionKeys(t *testing.T) { func TestServiceGetRuntimeVersion(t *testing.T) { t.Parallel() - testAPIItem := runtime.APIItem{ - Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, - Ver: 99, + rv := &runtime.VersionData{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: authoringVersion, + SpecVersion: specVersion, + ImplVersion: implVersion, + APIItems: []runtime.APIItem{{ + Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, + Ver: 99, + }}, + TransactionVersion: transactionVersion, } - rv := runtime.NewVersionData( - []byte("polkadot"), - []byte("parity-polkadot"), - authoringVersion, - specVersion, - implVersion, - []runtime.APIItem{testAPIItem}, - transactionVersion, - ) emptyTrie := trie.NewEmptyTrie() ts, err := rtstorage.NewTrieState(emptyTrie) require.NoError(t, err) diff --git a/dot/rpc/modules/api_mocks.go b/dot/rpc/modules/api_mocks.go index e46ce9e5a7f..b035c18d16b 100644 --- a/dot/rpc/modules/api_mocks.go +++ b/dot/rpc/modules/api_mocks.go @@ -7,7 +7,7 @@ import ( modulesmocks "github.com/ChainSafe/gossamer/dot/rpc/modules/mocks" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/common" - runtimemocks "github.com/ChainSafe/gossamer/lib/runtime/mocks" + "github.com/ChainSafe/gossamer/lib/runtime" "github.com/ChainSafe/gossamer/lib/transaction" "github.com/stretchr/testify/mock" ) @@ -63,22 +63,10 @@ func NewMockCoreAPI() *modulesmocks.CoreAPI { m := new(modulesmocks.CoreAPI) m.On("InsertKey", mock.AnythingOfType("crypto.Keypair"), mock.AnythingOfType("string")).Return(nil) m.On("HasKey", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(false, nil) - m.On("GetRuntimeVersion", mock.AnythingOfType("*common.Hash")).Return(NewMockVersion(), nil) + m.On("GetRuntimeVersion", mock.AnythingOfType("*common.Hash")). + Return(&runtime.VersionData{SpecName: []byte(`mock-spec`)}, 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.Version { - m := new(runtimemocks.Version) - 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 -} diff --git a/dot/rpc/modules/state.go b/dot/rpc/modules/state.go index 5306702905a..d3cd2e77a9e 100644 --- a/dot/rpc/modules/state.go +++ b/dot/rpc/modules/state.go @@ -300,13 +300,13 @@ func (sm *StateModule) GetRuntimeVersion( return err } - res.SpecName = string(rtVersion.SpecName()) - res.ImplName = string(rtVersion.ImplName()) - res.AuthoringVersion = rtVersion.AuthoringVersion() - res.SpecVersion = rtVersion.SpecVersion() - res.ImplVersion = rtVersion.ImplVersion() - res.TransactionVersion = rtVersion.TransactionVersion() - res.Apis = ConvertAPIs(rtVersion.APIItems()) + res.SpecName = string(rtVersion.GetSpecName()) + res.ImplName = string(rtVersion.GetImplName()) + res.AuthoringVersion = rtVersion.GetAuthoringVersion() + res.SpecVersion = rtVersion.GetSpecVersion() + res.ImplVersion = rtVersion.GetImplVersion() + res.TransactionVersion = rtVersion.GetTransactionVersion() + res.Apis = ConvertAPIs(rtVersion.GetAPIItems()) return nil } diff --git a/dot/rpc/modules/state_test.go b/dot/rpc/modules/state_test.go index 1d6a033f9dc..1d9da6322fe 100644 --- a/dot/rpc/modules/state_test.go +++ b/dot/rpc/modules/state_test.go @@ -447,19 +447,18 @@ func TestStateModuleGetReadProof(t *testing.T) { func TestStateModuleGetRuntimeVersion(t *testing.T) { hash := common.MustHexToHash("0x3aa96b0149b6ca3688878bdbd19464448624136398e3ce45b9e755d3ab61355a") - testAPIItem := runtime.APIItem{ - Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, - Ver: 99, - } - version := runtime.NewVersionData( - []byte("polkadot"), - []byte("parity-polkadot"), - 0, - 25, - 0, - []runtime.APIItem{testAPIItem}, - 5, - ) + version := &runtime.VersionData{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: 0, + SpecVersion: 25, + ImplVersion: 0, + APIItems: []runtime.APIItem{{ + Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, + Ver: 99, + }}, + TransactionVersion: 5, + } mockCoreAPI := new(mocks.CoreAPI) mockCoreAPI.On("GetRuntimeVersion", &hash).Return(version, nil) diff --git a/dot/rpc/subscription/listeners.go b/dot/rpc/subscription/listeners.go index 125438705ba..5ada8a9db50 100644 --- a/dot/rpc/subscription/listeners.go +++ b/dot/rpc/subscription/listeners.go @@ -410,13 +410,13 @@ func (l *RuntimeVersionListener) Listen() { return } ver := modules.StateRuntimeVersionResponse{} - ver.SpecName = string(rtVersion.SpecName()) - ver.ImplName = string(rtVersion.ImplName()) - ver.AuthoringVersion = rtVersion.AuthoringVersion() - ver.SpecVersion = rtVersion.SpecVersion() - ver.ImplVersion = rtVersion.ImplVersion() - ver.TransactionVersion = rtVersion.TransactionVersion() - ver.Apis = modules.ConvertAPIs(rtVersion.APIItems()) + ver.SpecName = string(rtVersion.GetSpecName()) + ver.ImplName = string(rtVersion.GetImplName()) + ver.AuthoringVersion = rtVersion.GetAuthoringVersion() + ver.SpecVersion = rtVersion.GetSpecVersion() + ver.ImplVersion = rtVersion.GetImplVersion() + ver.TransactionVersion = rtVersion.GetTransactionVersion() + ver.Apis = modules.ConvertAPIs(rtVersion.GetAPIItems()) go l.wsconn.safeSend(newSubscriptionResponse(stateRuntimeVersionMethod, l.subID, ver)) @@ -430,13 +430,13 @@ func (l *RuntimeVersionListener) Listen() { 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()) + ver.SpecName = string(info.GetSpecName()) + ver.ImplName = string(info.GetImplName()) + ver.AuthoringVersion = info.GetAuthoringVersion() + ver.SpecVersion = info.GetSpecVersion() + ver.ImplVersion = info.GetImplVersion() + ver.TransactionVersion = info.GetTransactionVersion() + ver.Apis = modules.ConvertAPIs(info.GetAPIItems()) l.wsconn.safeSend(newSubscriptionResponse(stateRuntimeVersionMethod, l.subID, ver)) } diff --git a/dot/rpc/subscription/listeners_test.go b/dot/rpc/subscription/listeners_test.go index 6576216e917..2595b678457 100644 --- a/dot/rpc/subscription/listeners_test.go +++ b/dot/rpc/subscription/listeners_test.go @@ -366,7 +366,7 @@ func TestRuntimeChannelListener_Listen(t *testing.T) { SpecVersion: 25, ImplVersion: 0, TransactionVersion: 5, - Apis: modules.ConvertAPIs(version.APIItems()), + Apis: modules.ConvertAPIs(version.GetAPIItems()), } expectedUpdateResponse := newSubcriptionBaseResponseJSON() diff --git a/dot/state/block.go b/dot/state/block.go index 5ac62332002..eeb8e13a718 100644 --- a/dot/state/block.go +++ b/dot/state/block.go @@ -598,7 +598,7 @@ func (bs *BlockState) HandleRuntimeChanges(newState *rtstorage.TrieState, // only update runtime during code substitution if runtime SpecVersion is updated previousVersion, _ := rt.Version() - if previousVersion.SpecVersion() == newVersion.SpecVersion() { + if previousVersion.GetSpecVersion() == newVersion.GetSpecVersion() { logger.Info("not upgrading runtime code during code substitution") bs.StoreRuntime(bHash, rt) return nil @@ -606,7 +606,7 @@ func (bs *BlockState) HandleRuntimeChanges(newState *rtstorage.TrieState, logger.Infof( "🔄 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 - bHash, codeHash, previousVersion.SpecVersion(), currCodeHash, newVersion.SpecVersion()) + bHash, codeHash, previousVersion.GetSpecVersion(), currCodeHash, newVersion.GetSpecVersion()) } rtCfg := &wasmer.Config{ diff --git a/dot/state/block_notify_test.go b/dot/state/block_notify_test.go index 9e8a05f5a99..6583a43b58c 100644 --- a/dot/state/block_notify_test.go +++ b/dot/state/block_notify_test.go @@ -10,7 +10,6 @@ import ( "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/runtime" - runtimemocks "github.com/ChainSafe/gossamer/lib/runtime/mocks" "github.com/stretchr/testify/require" ) @@ -149,7 +148,10 @@ func TestService_RegisterUnRegisterConcurrentCalls(t *testing.T) { go func() { for i := 0; i < 100; i++ { - testVer := NewMockVersion(uint32(i)) + testVer := &runtime.VersionData{ + SpecName: []byte("mock-spec"), + SpecVersion: uint32(i), + } go bs.notifyRuntimeUpdated(testVer) } }() @@ -165,16 +167,3 @@ func TestService_RegisterUnRegisterConcurrentCalls(t *testing.T) { }() } } - -// NewMockVersion creates and returns an runtime Version interface mock -func NewMockVersion(specVer uint32) *runtimemocks.Version { - m := new(runtimemocks.Version) - m.On("SpecName").Return([]byte(`mock-spec`)) - m.On("ImplName").Return(nil) - m.On("AuthoringVersion").Return(uint32(0)) - m.On("SpecVersion").Return(specVer) - m.On("ImplVersion").Return(uint32(0)) - m.On("TransactionVersion").Return(uint32(0)) - m.On("APIItems").Return(nil) - return m -} diff --git a/lib/babe/build_integration_test.go b/lib/babe/build_integration_test.go index 78694c8de0a..d80b92340fd 100644 --- a/lib/babe/build_integration_test.go +++ b/lib/babe/build_integration_test.go @@ -287,9 +287,9 @@ func TestBuildAndApplyExtrinsic(t *testing.T) { Era: ctypes.ExtrinsicEra{IsImmortalEra: true}, GenesisHash: genHash, Nonce: ctypes.NewUCompactFromUInt(uint64(0)), - SpecVersion: ctypes.U32(rv.SpecVersion()), + SpecVersion: ctypes.U32(rv.GetSpecVersion()), Tip: ctypes.NewUCompactFromUInt(0), - TransactionVersion: ctypes.U32(rv.TransactionVersion()), + TransactionVersion: ctypes.U32(rv.GetTransactionVersion()), } // Sign the transaction using Alice's default account diff --git a/lib/runtime/mocks/version.go b/lib/runtime/mocks/version.go deleted file mode 100644 index 264ceab55ef..00000000000 --- a/lib/runtime/mocks/version.go +++ /dev/null @@ -1,155 +0,0 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. - -package mocks - -import ( - runtime "github.com/ChainSafe/gossamer/lib/runtime" - mock "github.com/stretchr/testify/mock" -) - -// Version is an autogenerated mock type for the Version type -type Version struct { - mock.Mock -} - -// APIItems provides a mock function with given fields: -func (_m *Version) APIItems() []runtime.APIItem { - ret := _m.Called() - - var r0 []runtime.APIItem - if rf, ok := ret.Get(0).(func() []runtime.APIItem); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]runtime.APIItem) - } - } - - return r0 -} - -// AuthoringVersion provides a mock function with given fields: -func (_m *Version) AuthoringVersion() uint32 { - ret := _m.Called() - - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(uint32) - } - - return r0 -} - -// Encode provides a mock function with given fields: -func (_m *Version) Encode() ([]byte, error) { - ret := _m.Called() - - var r0 []byte - if rf, ok := ret.Get(0).(func() []byte); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]byte) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ImplName provides a mock function with given fields: -func (_m *Version) ImplName() []byte { - ret := _m.Called() - - var r0 []byte - if rf, ok := ret.Get(0).(func() []byte); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]byte) - } - } - - return r0 -} - -// ImplVersion provides a mock function with given fields: -func (_m *Version) ImplVersion() uint32 { - ret := _m.Called() - - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(uint32) - } - - return r0 -} - -// SpecName provides a mock function with given fields: -func (_m *Version) SpecName() []byte { - ret := _m.Called() - - var r0 []byte - if rf, ok := ret.Get(0).(func() []byte); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]byte) - } - } - - return r0 -} - -// SpecVersion provides a mock function with given fields: -func (_m *Version) SpecVersion() uint32 { - ret := _m.Called() - - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(uint32) - } - - return r0 -} - -// TransactionVersion provides a mock function with given fields: -func (_m *Version) TransactionVersion() uint32 { - ret := _m.Called() - - var r0 uint32 - if rf, ok := ret.Get(0).(func() uint32); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(uint32) - } - - return r0 -} - -type mockConstructorTestingTNewVersion interface { - mock.TestingT - Cleanup(func()) -} - -// NewVersion creates a new instance of Version. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewVersion(t mockConstructorTestingTNewVersion) *Version { - mock := &Version{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/lib/runtime/test_helpers.go b/lib/runtime/test_helpers.go index ac8c706986b..a4a2ceb5c0f 100644 --- a/lib/runtime/test_helpers.go +++ b/lib/runtime/test_helpers.go @@ -223,9 +223,9 @@ func NewTestExtrinsic(t *testing.T, rt Instance, genHash, blockHash common.Hash, Era: ctypes.ExtrinsicEra{IsImmortalEra: false}, GenesisHash: ctypes.Hash(genHash), Nonce: ctypes.NewUCompactFromUInt(nonce), - SpecVersion: ctypes.U32(rv.SpecVersion()), + SpecVersion: ctypes.U32(rv.GetSpecVersion()), Tip: ctypes.NewUCompactFromUInt(0), - TransactionVersion: ctypes.U32(rv.TransactionVersion()), + TransactionVersion: ctypes.U32(rv.GetTransactionVersion()), } // Sign the transaction using Alice's key diff --git a/lib/runtime/version.go b/lib/runtime/version.go index 4db1807eae2..c01a280d165 100644 --- a/lib/runtime/version.go +++ b/lib/runtime/version.go @@ -3,22 +3,22 @@ package runtime -import ( - "github.com/ChainSafe/gossamer/pkg/scale" -) - -//go:generate mockery --name Version --structname Version --case underscore --keeptree +import "github.com/ChainSafe/gossamer/pkg/scale" // Version represents the data returned by runtime call core_version type Version interface { - SpecName() []byte - ImplName() []byte - AuthoringVersion() uint32 - SpecVersion() uint32 - ImplVersion() uint32 - APIItems() []APIItem - TransactionVersion() uint32 - Encode() ([]byte, error) + GetSpecName() []byte + GetImplName() []byte + GetAuthoringVersion() uint32 + GetSpecVersion() uint32 + GetImplVersion() uint32 + GetAPIItems() []APIItem + GetTransactionVersion() uint32 + // Encode returns the scale encoding of the version. + // Note this one cannot be replaced by scale.Marshal + // or the Version interface pointer would be marshalled, + // instead of the version implementation. + Encode() (encoded []byte, err error) } // APIItem struct to hold runtime API Name and Version @@ -29,213 +29,101 @@ type APIItem struct { // LegacyVersionData is the runtime version info returned by legacy runtimes type LegacyVersionData struct { - specName []byte - implName []byte - authoringVersion uint32 - specVersion uint32 - implVersion uint32 - apiItems []APIItem -} - -// NewLegacyVersionData returns a new LegacyVersionData -func NewLegacyVersionData(specName, implName []byte, - authoringVersion, specVersion, implVersion uint32, - apiItems []APIItem) *LegacyVersionData { - return &LegacyVersionData{ - specName: specName, - implName: implName, - authoringVersion: authoringVersion, - specVersion: specVersion, - implVersion: implVersion, - apiItems: apiItems, - } + SpecName []byte + ImplName []byte + AuthoringVersion uint32 + SpecVersion uint32 + ImplVersion uint32 + APIItems []APIItem } -// SpecName returns the spec name -func (lvd *LegacyVersionData) SpecName() []byte { - return lvd.specName +// GetSpecName returns the spec name +func (lvd *LegacyVersionData) GetSpecName() []byte { + return lvd.SpecName } -// ImplName returns the implementation name -func (lvd *LegacyVersionData) ImplName() []byte { - return lvd.implName +// GetImplName returns the implementation name +func (lvd *LegacyVersionData) GetImplName() []byte { + return lvd.ImplName } -// AuthoringVersion returns the authoring version -func (lvd *LegacyVersionData) AuthoringVersion() uint32 { - return lvd.authoringVersion +// GetAuthoringVersion returns the authoring version +func (lvd *LegacyVersionData) GetAuthoringVersion() uint32 { + return lvd.AuthoringVersion } -// SpecVersion returns the spec version -func (lvd *LegacyVersionData) SpecVersion() uint32 { - return lvd.specVersion +// GetSpecVersion returns the spec version +func (lvd *LegacyVersionData) GetSpecVersion() uint32 { + return lvd.SpecVersion } -// ImplVersion returns the implementation version -func (lvd *LegacyVersionData) ImplVersion() uint32 { - return lvd.implVersion +// GetImplVersion returns the implementation version +func (lvd *LegacyVersionData) GetImplVersion() uint32 { + return lvd.ImplVersion } -// APIItems returns the API items -func (lvd *LegacyVersionData) APIItems() []APIItem { - return lvd.apiItems +// GetAPIItems returns the API items +func (lvd *LegacyVersionData) GetAPIItems() []APIItem { + return lvd.APIItems } -// TransactionVersion returns the transaction version -func (lvd *LegacyVersionData) TransactionVersion() uint32 { +// GetTransactionVersion returns the transaction version +func (lvd *LegacyVersionData) GetTransactionVersion() uint32 { return 0 } -type legacyVersionData struct { - SpecName []byte - ImplName []byte - AuthoringVersion uint32 - SpecVersion uint32 - ImplVersion uint32 - APIItems []APIItem -} - -// Encode returns the SCALE encoding of the Version -func (lvd *LegacyVersionData) Encode() ([]byte, error) { - info := legacyVersionData{ - SpecName: lvd.specName, - ImplName: lvd.implName, - AuthoringVersion: lvd.authoringVersion, - SpecVersion: lvd.specVersion, - ImplVersion: lvd.implVersion, - APIItems: lvd.apiItems, - } - - enc, err := scale.Marshal(info) - if err != nil { - return nil, err - } - return enc, nil -} - -// Decode to scale decode []byte to VersionAPI struct -func (lvd *LegacyVersionData) Decode(in []byte) error { - var info legacyVersionData - err := scale.Unmarshal(in, &info) - if err != nil { - return err - } - - lvd.specName = info.SpecName - lvd.implName = info.ImplName - lvd.authoringVersion = info.AuthoringVersion - lvd.specVersion = info.SpecVersion - lvd.implVersion = info.ImplVersion - lvd.apiItems = info.APIItems - - return nil +// Encode returns the scale encoding of the version. +func (lvd *LegacyVersionData) Encode() (encoded []byte, err error) { + return scale.Marshal(*lvd) } // VersionData is the runtime version info returned by v0.8 runtimes type VersionData struct { - specName []byte - implName []byte - authoringVersion uint32 - specVersion uint32 - implVersion uint32 - apiItems []APIItem - transactionVersion uint32 -} - -// NewVersionData returns a new VersionData -func NewVersionData(specName, implName []byte, - authoringVersion, specVersion, implVersion uint32, - apiItems []APIItem, transactionVersion uint32) *VersionData { - return &VersionData{ - specName: specName, - implName: implName, - authoringVersion: authoringVersion, - specVersion: specVersion, - implVersion: implVersion, - apiItems: apiItems, - transactionVersion: transactionVersion, - } -} - -// SpecName returns the spec name -func (vd *VersionData) SpecName() []byte { - return vd.specName + SpecName []byte + ImplName []byte + AuthoringVersion uint32 + SpecVersion uint32 + ImplVersion uint32 + APIItems []APIItem + TransactionVersion uint32 } -// ImplName returns the implementation name -func (vd *VersionData) ImplName() []byte { - return vd.implName +// GetSpecName returns the spec name +func (vd *VersionData) GetSpecName() []byte { + return vd.SpecName } -// AuthoringVersion returns the authoring version -func (vd *VersionData) AuthoringVersion() uint32 { - return vd.authoringVersion +// GetImplName returns the implementation name +func (vd *VersionData) GetImplName() []byte { + return vd.ImplName } -// SpecVersion returns the spec version -func (vd *VersionData) SpecVersion() uint32 { - return vd.specVersion +// GetAuthoringVersion returns the authoring version +func (vd *VersionData) GetAuthoringVersion() uint32 { + return vd.AuthoringVersion } -// ImplVersion returns the implementation version -func (vd *VersionData) ImplVersion() uint32 { - return vd.implVersion +// GetSpecVersion returns the spec version +func (vd *VersionData) GetSpecVersion() uint32 { + return vd.SpecVersion } -// APIItems returns the API items -func (vd *VersionData) APIItems() []APIItem { - return vd.apiItems +// GetImplVersion returns the implementation version +func (vd *VersionData) GetImplVersion() uint32 { + return vd.ImplVersion } -// TransactionVersion returns the transaction version -func (vd *VersionData) TransactionVersion() uint32 { - return vd.transactionVersion +// GetAPIItems returns the API items +func (vd *VersionData) GetAPIItems() []APIItem { + return vd.APIItems } -type versionData struct { - SpecName []byte - ImplName []byte - AuthoringVersion uint32 - SpecVersion uint32 - ImplVersion uint32 - APIItems []APIItem - TransactionVersion uint32 +// GetTransactionVersion returns the transaction version +func (vd *VersionData) GetTransactionVersion() uint32 { + return vd.TransactionVersion } -// Encode returns the SCALE encoding of the Version -func (vd *VersionData) Encode() ([]byte, error) { - info := versionData{ - SpecName: vd.specName, - ImplName: vd.implName, - AuthoringVersion: vd.authoringVersion, - SpecVersion: vd.specVersion, - ImplVersion: vd.implVersion, - APIItems: vd.apiItems, - TransactionVersion: vd.transactionVersion, - } - - enc, err := scale.Marshal(info) - if err != nil { - return nil, err - } - return enc, nil -} - -// Decode to scale decode []byte to VersionAPI struct -func (vd *VersionData) Decode(in []byte) error { - var info versionData - err := scale.Unmarshal(in, &info) - if err != nil { - return err - } - - vd.specName = info.SpecName - vd.implName = info.ImplName - vd.authoringVersion = info.AuthoringVersion - vd.specVersion = info.SpecVersion - vd.implVersion = info.ImplVersion - vd.apiItems = info.APIItems - vd.transactionVersion = info.TransactionVersion - - return nil +// Encode returns the scale encoding of the version. +func (vd *VersionData) Encode() (encoded []byte, err error) { + return scale.Marshal(*vd) } diff --git a/lib/runtime/version_test.go b/lib/runtime/version_test.go index 914564ecfde..d97cd84a4e5 100644 --- a/lib/runtime/version_test.go +++ b/lib/runtime/version_test.go @@ -6,54 +6,71 @@ package runtime import ( "testing" + "github.com/ChainSafe/gossamer/pkg/scale" "github.com/stretchr/testify/require" ) -func TestVersionData(t *testing.T) { - testAPIItem := APIItem{ - Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, - Ver: 99, +func Test_VersionData_Scale(t *testing.T) { + version := VersionData{ + SpecName: []byte{1}, + ImplName: []byte{2}, + AuthoringVersion: 3, + SpecVersion: 4, + ImplVersion: 5, + APIItems: []APIItem{{ + Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, + Ver: 6, + }}, + TransactionVersion: 7, } - version := NewVersionData( - []byte("polkadot"), - []byte("parity-polkadot"), - 0, - 25, - 0, - []APIItem{testAPIItem}, - 5, - ) - - b, err := version.Encode() + expectedScale := []byte{ + 0x4, 0x1, 0x4, 0x2, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x5, 0x0, 0x0, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x6, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0} + + scaleEncoded, err := scale.Marshal(version) + require.NoError(t, err) + require.Equal(t, expectedScale, scaleEncoded) + + encoding, err := version.Encode() require.NoError(t, err) + require.Equal(t, expectedScale, encoding) - dec := new(VersionData) - err = dec.Decode(b) + var decoded VersionData + err = scale.Unmarshal(scaleEncoded, &decoded) require.NoError(t, err) - require.Equal(t, version, dec) + require.Equal(t, version, decoded) } -func TestLegacyVersionData(t *testing.T) { - testAPIItem := APIItem{ - Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, - Ver: 99, +func Test_LegacyVersionData_Scale(t *testing.T) { + version := LegacyVersionData{ + SpecName: []byte{1}, + ImplName: []byte{2}, + AuthoringVersion: 3, + SpecVersion: 4, + ImplVersion: 5, + APIItems: []APIItem{{ + Name: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}, + Ver: 6, + }}, } - version := NewLegacyVersionData( - []byte("polkadot"), - []byte("parity-polkadot"), - 0, - 25, - 0, - []APIItem{testAPIItem}, - ) + expectedScale := []byte{ + 0x4, 0x1, 0x4, 0x2, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x5, 0x0, 0x0, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x6, 0x0, 0x0, 0x0} + + scaleEncoded, err := scale.Marshal(version) + require.NoError(t, err) + require.Equal(t, expectedScale, scaleEncoded) - b, err := version.Encode() + encoding, err := version.Encode() require.NoError(t, err) + require.Equal(t, expectedScale, encoding) - dec := new(LegacyVersionData) - err = dec.Decode(b) + var decoded LegacyVersionData + err = scale.Unmarshal(scaleEncoded, &decoded) require.NoError(t, err) - require.Equal(t, version, dec) + require.Equal(t, version, decoded) } diff --git a/lib/runtime/wasmer/exports.go b/lib/runtime/wasmer/exports.go index 7e22fcfc6e0..67dabf26ebf 100644 --- a/lib/runtime/wasmer/exports.go +++ b/lib/runtime/wasmer/exports.go @@ -39,13 +39,14 @@ func (in *Instance) Version() (runtime.Version, error) { } version := &runtime.VersionData{} - err = version.Decode(res) + err = scale.Unmarshal(res, version) // error comes from scale now, so do a string check if err != nil { if strings.Contains(err.Error(), "EOF") { + // TODO io.EOF should be wrapped in scale // TODO: kusama seems to use the legacy version format lversion := &runtime.LegacyVersionData{} - err = lversion.Decode(res) + err = scale.Unmarshal(res, lversion) return lversion, err } return nil, err diff --git a/lib/runtime/wasmer/exports_test.go b/lib/runtime/wasmer/exports_test.go index 2d20264b952..00171375c4c 100644 --- a/lib/runtime/wasmer/exports_test.go +++ b/lib/runtime/wasmer/exports_test.go @@ -12,6 +12,7 @@ import ( "testing" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/ed25519" "github.com/ChainSafe/gossamer/lib/genesis" @@ -26,253 +27,264 @@ import ( "github.com/stretchr/testify/require" ) -func TestInstance_Version_NodeRuntime_v098(t *testing.T) { - expected := runtime.NewVersionData( - []byte("node"), - []byte("substrate-node"), - 10, - 267, - 0, - nil, - 2, - ) - - instance := NewTestInstance(t, runtime.NODE_RUNTIME_v098) - - version, err := instance.Version() - require.NoError(t, err) - - t.Logf("SpecName: %s\n", version.SpecName()) - t.Logf("ImplName: %s\n", version.ImplName()) - t.Logf("AuthoringVersion: %d\n", version.AuthoringVersion()) - t.Logf("SpecVersion: %d\n", version.SpecVersion()) - t.Logf("ImplVersion: %d\n", version.ImplVersion()) - t.Logf("TransactionVersion: %d\n", version.TransactionVersion()) - - require.Equal(t, 13, len(version.APIItems())) - require.Equal(t, expected.SpecName(), version.SpecName()) - require.Equal(t, expected.ImplName(), version.ImplName()) - require.Equal(t, expected.AuthoringVersion(), version.AuthoringVersion()) - require.Equal(t, expected.SpecVersion(), version.SpecVersion()) - require.Equal(t, expected.ImplVersion(), version.ImplVersion()) - require.Equal(t, expected.TransactionVersion(), version.TransactionVersion()) -} - -func TestInstance_Version_PolkadotRuntime_v0910(t *testing.T) { - expected := runtime.NewVersionData( - []byte("polkadot"), - []byte("parity-polkadot"), - 0, - 9100, - 0, - nil, - 8, - ) - - instance := NewTestInstance(t, runtime.POLKADOT_RUNTIME_v0910) - version, err := instance.Version() - require.NoError(t, err) - - t.Logf("SpecName: %s\n", version.SpecName()) - t.Logf("ImplName: %s\n", version.ImplName()) - t.Logf("AuthoringVersion: %d\n", version.AuthoringVersion()) - t.Logf("SpecVersion: %d\n", version.SpecVersion()) - t.Logf("ImplVersion: %d\n", version.ImplVersion()) - t.Logf("TransactionVersion: %d\n", version.TransactionVersion()) - - require.Equal(t, 14, len(version.APIItems())) - require.Equal(t, expected.SpecName(), version.SpecName()) - require.Equal(t, expected.ImplName(), version.ImplName()) - require.Equal(t, expected.AuthoringVersion(), version.AuthoringVersion()) - require.Equal(t, expected.SpecVersion(), version.SpecVersion()) - require.Equal(t, expected.ImplVersion(), version.ImplVersion()) - require.Equal(t, expected.TransactionVersion(), version.TransactionVersion()) -} - -func TestInstance_Version_PolkadotRuntime_v0917(t *testing.T) { - instance := NewTestInstance(t, runtime.POLKADOT_RUNTIME_v0917) - version, err := instance.Version() - require.NoError(t, err) - - expectedSpecName := []byte("polkadot") - expectedImplName := []byte("parity-polkadot") - const ( - expectedAuthoringVersion uint32 = 0 - expectedSpecVersion uint32 = 9170 - expectedImplVersion uint32 = 0 - expectedTransactionVersion uint32 = 11 - ) - expectedAPIItems := []runtime.APIItem{ - {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x4}, - {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, - {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x5}, - {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x3}, - {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, - {Name: [8]uint8{0xaf, 0x2c, 0x2, 0x97, 0xa2, 0x3e, 0x6d, 0x3d}, Ver: 0x2}, - {Name: [8]uint8{0x49, 0xea, 0xaf, 0x1b, 0x54, 0x8a, 0xc, 0xb0}, Ver: 0x1}, - {Name: [8]uint8{0x91, 0xd5, 0xdf, 0x18, 0xb0, 0xd2, 0xcf, 0x58}, Ver: 0x1}, - {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x3}, - {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, - {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, - {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, - {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, - {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, +func Test_Instance_Version(t *testing.T) { + type InstanceVersion interface { + Version() (runtime.Version, error) } - assert.Equal(t, expectedAPIItems, version.APIItems()) - assert.Equal(t, expectedSpecName, version.SpecName()) - assert.Equal(t, expectedImplName, version.ImplName()) - assert.Equal(t, expectedAuthoringVersion, version.AuthoringVersion()) - assert.Equal(t, expectedSpecVersion, version.SpecVersion()) - assert.Equal(t, expectedImplVersion, version.ImplVersion()) - assert.Equal(t, expectedTransactionVersion, version.TransactionVersion()) -} - -func TestInstance_Version_PolkadotRuntime(t *testing.T) { - expected := runtime.NewVersionData( - []byte("polkadot"), - []byte("parity-polkadot"), - 0, - 25, - 0, - nil, - 5, - ) - - instance := NewTestInstance(t, runtime.POLKADOT_RUNTIME) - - version, err := instance.Version() - require.NoError(t, err) - - t.Logf("SpecName: %s\n", version.SpecName()) - t.Logf("ImplName: %s\n", version.ImplName()) - t.Logf("AuthoringVersion: %d\n", version.AuthoringVersion()) - t.Logf("SpecVersion: %d\n", version.SpecVersion()) - t.Logf("ImplVersion: %d\n", version.ImplVersion()) - t.Logf("TransactionVersion: %d\n", version.TransactionVersion()) - - require.Equal(t, 12, len(version.APIItems())) - require.Equal(t, expected.SpecName(), version.SpecName()) - require.Equal(t, expected.ImplName(), version.ImplName()) - require.Equal(t, expected.AuthoringVersion(), version.AuthoringVersion()) - require.Equal(t, expected.SpecVersion(), version.SpecVersion()) - require.Equal(t, expected.ImplVersion(), version.ImplVersion()) - require.Equal(t, expected.TransactionVersion(), version.TransactionVersion()) -} - -func TestInstance_Version_KusamaRuntime(t *testing.T) { - genesisPath := utils.GetKusamaGenesisPath(t) - gen, err := genesis.NewGenesisFromJSONRaw(genesisPath) - require.NoError(t, err) - - genTrie, err := genesis.NewTrieFromGenesis(gen) - require.NoError(t, err) - - expectedGenesisRoot := common.MustHexToHash("0xb0006203c3a6e6bd2c6a17b1d4ae8ca49a31da0f4579da950b127774b44aef6b") - require.Equal(t, expectedGenesisRoot, genTrie.MustHash()) - - // set state to genesis state - genState, err := storage.NewTrieState(genTrie) - require.NoError(t, err) - - cfg := &Config{} - cfg.Storage = genState - cfg.LogLvl = 4 - - instance, err := NewRuntimeFromGenesis(cfg) - require.NoError(t, err) - - expected := runtime.NewVersionData( - []byte("kusama"), - []byte("parity-kusama"), - 2, - 1020, - 0, - nil, - 0, - ) - - version, err := instance.(*Instance).Version() - require.NoError(t, err) - - t.Logf("SpecName: %s\n", version.SpecName()) - t.Logf("ImplName: %s\n", version.ImplName()) - t.Logf("AuthoringVersion: %d\n", version.AuthoringVersion()) - t.Logf("SpecVersion: %d\n", version.SpecVersion()) - t.Logf("ImplVersion: %d\n", version.ImplVersion()) - t.Logf("TransactionVersion: %d\n", version.TransactionVersion()) - - require.Equal(t, 12, len(version.APIItems())) - require.Equal(t, expected.SpecName(), version.SpecName()) - require.Equal(t, expected.ImplName(), version.ImplName()) - require.Equal(t, expected.AuthoringVersion(), version.AuthoringVersion()) - require.Equal(t, expected.SpecVersion(), version.SpecVersion()) - require.Equal(t, expected.ImplVersion(), version.ImplVersion()) - require.Equal(t, expected.TransactionVersion(), version.TransactionVersion()) -} - -func TestInstance_Version_NodeRuntime(t *testing.T) { - expected := runtime.NewVersionData( - []byte("node"), - []byte("substrate-node"), - 10, - 264, - 0, - nil, - 2, - ) - - instance := NewTestInstance(t, runtime.NODE_RUNTIME) - - version, err := instance.Version() - require.NoError(t, err) - - t.Logf("SpecName: %s\n", version.SpecName()) - t.Logf("ImplName: %s\n", version.ImplName()) - t.Logf("AuthoringVersion: %d\n", version.AuthoringVersion()) - t.Logf("SpecVersion: %d\n", version.SpecVersion()) - t.Logf("ImplVersion: %d\n", version.ImplVersion()) - t.Logf("TransactionVersion: %d\n", version.TransactionVersion()) + testCases := map[string]struct { + instanceBuilder func(t *testing.T) InstanceVersion + expectedVersion runtime.Version + }{ + "dev": { + instanceBuilder: func(t *testing.T) InstanceVersion { + return NewTestInstance(t, runtime.DEV_RUNTIME) + }, + expectedVersion: &runtime.VersionData{ + SpecName: []byte("node"), + ImplName: []byte("gossamer-node"), + AuthoringVersion: 10, + SpecVersion: 260, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x3}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x4}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x2}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x2}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x68, 0xb6, 0x6b, 0xa1, 0x22, 0xc9, 0x3f, 0xa7}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + }, + TransactionVersion: 1, + }, + }, + "node v098": { + instanceBuilder: func(t *testing.T) InstanceVersion { + return NewTestInstance(t, runtime.NODE_RUNTIME_v098) + }, + expectedVersion: &runtime.VersionData{ + SpecName: []byte("node"), + ImplName: []byte("substrate-node"), + AuthoringVersion: 10, + SpecVersion: 267, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x3}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x5}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x2}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x2}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x68, 0xb6, 0x6b, 0xa1, 0x22, 0xc9, 0x3f, 0xa7}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + {Name: [8]uint8{0x91, 0xd5, 0xdf, 0x18, 0xb0, 0xd2, 0xcf, 0x58}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + }, + TransactionVersion: 2, + }, + }, + "node": { + instanceBuilder: func(t *testing.T) InstanceVersion { + return NewTestInstance(t, runtime.NODE_RUNTIME) + }, + expectedVersion: &runtime.VersionData{ + SpecName: []byte("node"), + ImplName: []byte("substrate-node"), + AuthoringVersion: 10, + SpecVersion: 264, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x3}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x4}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x2}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x2}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x68, 0xb6, 0x6b, 0xa1, 0x22, 0xc9, 0x3f, 0xa7}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + {Name: [8]uint8{0x91, 0xd5, 0xdf, 0x18, 0xb0, 0xd2, 0xcf, 0x58}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + }, + TransactionVersion: 2, + }, + }, + "kusama": { + instanceBuilder: func(t *testing.T) InstanceVersion { + genesisPath := utils.GetKusamaGenesisPath(t) + kusamaGenesis, err := genesis.NewGenesisFromJSONRaw(genesisPath) + require.NoError(t, err) + genesisTrie, err := genesis.NewTrieFromGenesis(kusamaGenesis) + require.NoError(t, err) + trieState, err := storage.NewTrieState(genesisTrie) + require.NoError(t, err) + + cfg := new(Config) + cfg.Storage = trieState + cfg.LogLvl = log.Critical + + instance, err := NewRuntimeFromGenesis(cfg) + require.NoError(t, err) + return instance + }, + expectedVersion: &runtime.LegacyVersionData{ + SpecName: []byte("kusama"), + ImplName: []byte("parity-kusama"), + AuthoringVersion: 2, + SpecVersion: 1020, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x2}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x4}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x1}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x1}, + {Name: [8]uint8{0xaf, 0x2c, 0x2, 0x97, 0xa2, 0x3e, 0x6d, 0x3d}, Ver: 0x1}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x2}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x1}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + }, + }, + }, + "polkadot v0825": { + instanceBuilder: func(t *testing.T) InstanceVersion { + return NewTestInstance(t, runtime.POLKADOT_RUNTIME) + }, + expectedVersion: &runtime.VersionData{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: 0, + SpecVersion: 25, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x3}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x4}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x2}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, + {Name: [8]uint8{0xaf, 0x2c, 0x2, 0x97, 0xa2, 0x3e, 0x6d, 0x3d}, Ver: 0x1}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x2}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + }, + TransactionVersion: 5, + }, + }, + "polkadot v0910": { + instanceBuilder: func(t *testing.T) InstanceVersion { + return NewTestInstance(t, runtime.POLKADOT_RUNTIME_v0910) + }, + expectedVersion: &runtime.VersionData{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: 0, + SpecVersion: 9100, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x3}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x5}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x3}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, + {Name: [8]uint8{0xaf, 0x2c, 0x2, 0x97, 0xa2, 0x3e, 0x6d, 0x3d}, Ver: 0x1}, + {Name: [8]uint8{0x49, 0xea, 0xaf, 0x1b, 0x54, 0x8a, 0xc, 0xb0}, Ver: 0x1}, + {Name: [8]uint8{0x91, 0xd5, 0xdf, 0x18, 0xb0, 0xd2, 0xcf, 0x58}, Ver: 0x1}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x3}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + }, + TransactionVersion: 8, + }, + }, + "runtime v0980": { + instanceBuilder: func(t *testing.T) InstanceVersion { + return NewTestInstance(t, runtime.NODE_RUNTIME_v098) + }, + expectedVersion: &runtime.VersionData{ + SpecName: []byte("node"), + ImplName: []byte("substrate-node"), + AuthoringVersion: 10, + SpecVersion: 267, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x3}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x5}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x2}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x2}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x68, 0xb6, 0x6b, 0xa1, 0x22, 0xc9, 0x3f, 0xa7}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + {Name: [8]uint8{0x91, 0xd5, 0xdf, 0x18, 0xb0, 0xd2, 0xcf, 0x58}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + }, + TransactionVersion: 2, + }, + }, + "polkadot v0917": { + instanceBuilder: func(t *testing.T) InstanceVersion { + return NewTestInstance(t, runtime.POLKADOT_RUNTIME_v0917) + }, + expectedVersion: &runtime.VersionData{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: 0, + SpecVersion: 9170, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x4}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x5}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x3}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, + {Name: [8]uint8{0xaf, 0x2c, 0x2, 0x97, 0xa2, 0x3e, 0x6d, 0x3d}, Ver: 0x2}, + {Name: [8]uint8{0x49, 0xea, 0xaf, 0x1b, 0x54, 0x8a, 0xc, 0xb0}, Ver: 0x1}, + {Name: [8]uint8{0x91, 0xd5, 0xdf, 0x18, 0xb0, 0xd2, 0xcf, 0x58}, Ver: 0x1}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x3}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + }, + TransactionVersion: 11, + }, + }, + } - require.Equal(t, 13, len(version.APIItems())) - require.Equal(t, expected.SpecName(), version.SpecName()) - require.Equal(t, expected.ImplName(), version.ImplName()) - require.Equal(t, expected.AuthoringVersion(), version.AuthoringVersion()) - require.Equal(t, expected.SpecVersion(), version.SpecVersion()) - require.Equal(t, expected.ImplVersion(), version.ImplVersion()) - require.Equal(t, expected.TransactionVersion(), version.TransactionVersion()) -} + for name, testCase := range testCases { + testCase := testCase + t.Run(name, func(t *testing.T) { + t.Parallel() -func TestInstance_Version_DevRuntime(t *testing.T) { - expected := runtime.NewVersionData( - []byte("node"), - []byte("gossamer-node"), - 10, - 260, - 0, - nil, - 1, - ) - - instance := NewTestInstance(t, runtime.DEV_RUNTIME) - - version, err := instance.Version() - require.NoError(t, err) - - t.Logf("SpecName: %s\n", version.SpecName()) - t.Logf("ImplName: %s\n", version.ImplName()) - t.Logf("AuthoringVersion: %d\n", version.AuthoringVersion()) - t.Logf("SpecVersion: %d\n", version.SpecVersion()) - t.Logf("ImplVersion: %d\n", version.ImplVersion()) - t.Logf("TransactionVersion: %d\n", version.TransactionVersion()) - - require.Equal(t, 12, len(version.APIItems())) - require.Equal(t, expected.SpecName(), version.SpecName()) - require.Equal(t, expected.ImplName(), version.ImplName()) - require.Equal(t, expected.AuthoringVersion(), version.AuthoringVersion()) - require.Equal(t, expected.SpecVersion(), version.SpecVersion()) - require.Equal(t, expected.ImplVersion(), version.ImplVersion()) - require.Equal(t, expected.TransactionVersion(), version.TransactionVersion()) + instance := testCase.instanceBuilder(t) + version, err := instance.Version() + require.NoError(t, err) + assert.Equal(t, testCase.expectedVersion, version) + }) + } } func balanceKey(t *testing.T, pub []byte) []byte { @@ -766,7 +778,7 @@ func TestInstance_ExecuteBlock_KusamaRuntime_KusamaBlock901442(t *testing.T) { cfg := &Config{} cfg.Storage = state901441 - cfg.LogLvl = 4 + cfg.LogLvl = log.Critical instance, err := NewInstanceFromTrie(ksmTrie901441, cfg) require.NoError(t, err) diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index 0d9d8539ac3..304855a986c 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -960,6 +960,9 @@ func ext_misc_runtime_version_version_1(context unsafe.Pointer, dataSpan C.int64 return C.int64_t(out) } + // Note: we must call the `Encode` method and NOT + // scale.Marshal or this one would encode the Version + // interface but not the actual implementation. encodedData, err := version.Encode() if err != nil { logger.Errorf("failed to encode result: %s", err) diff --git a/lib/runtime/wasmer/instance.go b/lib/runtime/wasmer/instance.go index ff2d454780d..0957b79f534 100644 --- a/lib/runtime/wasmer/instance.go +++ b/lib/runtime/wasmer/instance.go @@ -151,7 +151,6 @@ func NewInstance(code []byte, cfg *Config) (*Instance, error) { OffchainHTTPSet: offchain.NewHTTPSet(), } - logger.Debugf("NewInstance called with runtimeCtx: %v", runtimeCtx) instance.SetContextData(runtimeCtx) inst := &Instance{ diff --git a/lib/runtime/wasmer/instance_test.go b/lib/runtime/wasmer/instance_test.go index 97b50c3bc54..50da851d6b1 100644 --- a/lib/runtime/wasmer/instance_test.go +++ b/lib/runtime/wasmer/instance_test.go @@ -46,23 +46,30 @@ func TestInstance_CheckRuntimeVersion(t *testing.T) { version, err := instance.CheckRuntimeVersion(code) require.NoError(t, err) - expected := runtime.NewVersionData( - []byte("polkadot"), - []byte("parity-polkadot"), - 0, - 25, - 0, - nil, - 5, - ) + expected := &runtime.VersionData{ + SpecName: []byte("polkadot"), + ImplName: []byte("parity-polkadot"), + AuthoringVersion: 0, + SpecVersion: 25, + ImplVersion: 0, + APIItems: []runtime.APIItem{ + {Name: [8]uint8{0xdf, 0x6a, 0xcb, 0x68, 0x99, 0x7, 0x60, 0x9b}, Ver: 0x3}, + {Name: [8]uint8{0x37, 0xe3, 0x97, 0xfc, 0x7c, 0x91, 0xf5, 0xe4}, Ver: 0x1}, + {Name: [8]uint8{0x40, 0xfe, 0x3a, 0xd4, 0x1, 0xf8, 0x95, 0x9a}, Ver: 0x4}, + {Name: [8]uint8{0xd2, 0xbc, 0x98, 0x97, 0xee, 0xd0, 0x8f, 0x15}, Ver: 0x2}, + {Name: [8]uint8{0xf7, 0x8b, 0x27, 0x8b, 0xe5, 0x3f, 0x45, 0x4c}, Ver: 0x2}, + {Name: [8]uint8{0xaf, 0x2c, 0x2, 0x97, 0xa2, 0x3e, 0x6d, 0x3d}, Ver: 0x1}, + {Name: [8]uint8{0xed, 0x99, 0xc5, 0xac, 0xb2, 0x5e, 0xed, 0xf5}, Ver: 0x2}, + {Name: [8]uint8{0xcb, 0xca, 0x25, 0xe3, 0x9f, 0x14, 0x23, 0x87}, Ver: 0x2}, + {Name: [8]uint8{0x68, 0x7a, 0xd4, 0x4a, 0xd3, 0x7f, 0x3, 0xc2}, Ver: 0x1}, + {Name: [8]uint8{0xab, 0x3c, 0x5, 0x72, 0x29, 0x1f, 0xeb, 0x8b}, Ver: 0x1}, + {Name: [8]uint8{0xbc, 0x9d, 0x89, 0x90, 0x4f, 0x5b, 0x92, 0x3f}, Ver: 0x1}, + {Name: [8]uint8{0x37, 0xc8, 0xbb, 0x13, 0x50, 0xa9, 0xa2, 0xa8}, Ver: 0x1}, + }, + TransactionVersion: 5, + } - require.Equal(t, 12, len(version.APIItems())) - require.Equal(t, expected.SpecName(), version.SpecName()) - require.Equal(t, expected.ImplName(), version.ImplName()) - require.Equal(t, expected.AuthoringVersion(), version.AuthoringVersion()) - require.Equal(t, expected.SpecVersion(), version.SpecVersion()) - require.Equal(t, expected.ImplVersion(), version.ImplVersion()) - require.Equal(t, expected.TransactionVersion(), version.TransactionVersion()) + require.Equal(t, expected, version) } func TestDecompressWasm(t *testing.T) {