Skip to content

Commit 31e2cc9

Browse files
committed
refactor: attach metadata to api modules
1 parent 301443d commit 31e2cc9

File tree

26 files changed

+912
-496
lines changed

26 files changed

+912
-496
lines changed

api/account_nonce/module.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package account_nonce
33
import (
44
"bytes"
55

6+
sc "github.com/LimeChain/goscale"
7+
"github.com/LimeChain/gosemble/constants/metadata"
68
"github.com/LimeChain/gosemble/frame/system"
79
"github.com/LimeChain/gosemble/primitives/hashing"
810
"github.com/LimeChain/gosemble/primitives/log"
@@ -59,3 +61,25 @@ func (m Module[T]) AccountNonce(dataPtr int32, dataLen int32) int64 {
5961

6062
return m.memUtils.BytesToOffsetAndSize(nonce.Bytes())
6163
}
64+
65+
func (m Module[T]) Metadata() types.RuntimeApiMetadata {
66+
methods := sc.Sequence[types.RuntimeApiMethodMetadata]{
67+
types.RuntimeApiMethodMetadata{
68+
Name: "account_nonce",
69+
Inputs: sc.Sequence[types.RuntimeApiMethodParamMetadata]{
70+
types.RuntimeApiMethodParamMetadata{
71+
Name: "account",
72+
Type: sc.ToCompact(metadata.TypesAddress32),
73+
},
74+
},
75+
Output: sc.ToCompact(metadata.PrimitiveTypesU32),
76+
Docs: sc.Sequence[sc.Str]{" Get current account nonce of given `AccountId`."},
77+
},
78+
}
79+
80+
return types.RuntimeApiMetadata{
81+
Name: ApiModuleName,
82+
Methods: methods,
83+
Docs: sc.Sequence[sc.Str]{" The API to query account nonce."},
84+
}
85+
}

api/account_nonce/module_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/ChainSafe/gossamer/lib/common"
77
sc "github.com/LimeChain/goscale"
88
"github.com/LimeChain/gosemble/constants"
9+
"github.com/LimeChain/gosemble/constants/metadata"
910
"github.com/LimeChain/gosemble/mocks"
1011
"github.com/LimeChain/gosemble/primitives/types"
1112
"github.com/stretchr/testify/assert"
@@ -55,6 +56,30 @@ func Test_Module_AccountNonce(t *testing.T) {
5556
mockMemoryUtils.AssertCalled(t, "BytesToOffsetAndSize", nonce.Bytes())
5657
}
5758

59+
func Test_Module_Metadata(t *testing.T) {
60+
target := setup()
61+
62+
expect := types.RuntimeApiMetadata{
63+
Name: ApiModuleName,
64+
Methods: sc.Sequence[types.RuntimeApiMethodMetadata]{
65+
types.RuntimeApiMethodMetadata{
66+
Name: "account_nonce",
67+
Inputs: sc.Sequence[types.RuntimeApiMethodParamMetadata]{
68+
types.RuntimeApiMethodParamMetadata{
69+
Name: "account",
70+
Type: sc.ToCompact(metadata.TypesAddress32),
71+
},
72+
},
73+
Output: sc.ToCompact(metadata.PrimitiveTypesU32),
74+
Docs: sc.Sequence[sc.Str]{" Get current account nonce of given `AccountId`."},
75+
},
76+
},
77+
Docs: sc.Sequence[sc.Str]{" The API to query account nonce."},
78+
}
79+
80+
assert.Equal(t, expect, target.Metadata())
81+
}
82+
5883
func setup() Module[types.Ed25519PublicKey] {
5984
mockSystem = new(mocks.SystemModule)
6085
mockMemoryUtils = new(mocks.MemoryTranslator)

api/aura/module.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package aura
22

33
import (
44
sc "github.com/LimeChain/goscale"
5+
"github.com/LimeChain/gosemble/constants/metadata"
56
"github.com/LimeChain/gosemble/frame/aura"
67
"github.com/LimeChain/gosemble/primitives/hashing"
78
"github.com/LimeChain/gosemble/primitives/log"
@@ -56,3 +57,26 @@ func (m Module) SlotDuration() int64 {
5657
slotDuration := m.aura.SlotDuration()
5758
return m.memUtils.BytesToOffsetAndSize(slotDuration.Bytes())
5859
}
60+
61+
func (m Module) Metadata() primitives.RuntimeApiMetadata {
62+
methods := sc.Sequence[primitives.RuntimeApiMethodMetadata]{
63+
primitives.RuntimeApiMethodMetadata{
64+
Name: "authorities",
65+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{},
66+
Output: sc.ToCompact(metadata.TypesSequenceU8),
67+
Docs: sc.Sequence[sc.Str]{""},
68+
},
69+
primitives.RuntimeApiMethodMetadata{
70+
Name: "slot_duration",
71+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{},
72+
Output: sc.ToCompact(metadata.PrimitiveTypesU64),
73+
Docs: sc.Sequence[sc.Str]{},
74+
},
75+
}
76+
77+
return primitives.RuntimeApiMetadata{
78+
Name: ApiModuleName,
79+
Methods: methods,
80+
Docs: sc.Sequence[sc.Str]{" The API to query account nonce."},
81+
}
82+
}

api/aura/module_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/ChainSafe/gossamer/lib/common"
77
sc "github.com/LimeChain/goscale"
8+
"github.com/LimeChain/gosemble/constants/metadata"
89
"github.com/LimeChain/gosemble/mocks"
910
"github.com/LimeChain/gosemble/primitives/types"
1011
"github.com/stretchr/testify/assert"
@@ -83,3 +84,28 @@ func Test_SlotDuration(t *testing.T) {
8384
mockAura.AssertCalled(t, "SlotDuration")
8485
mockMemoryUtils.AssertCalled(t, "BytesToOffsetAndSize", durationBytes)
8586
}
87+
88+
func Test_Module_Metadata(t *testing.T) {
89+
setup()
90+
91+
expect := types.RuntimeApiMetadata{
92+
Name: ApiModuleName,
93+
Methods: sc.Sequence[types.RuntimeApiMethodMetadata]{
94+
types.RuntimeApiMethodMetadata{
95+
Name: "authorities",
96+
Inputs: sc.Sequence[types.RuntimeApiMethodParamMetadata]{},
97+
Output: sc.ToCompact(metadata.TypesSequenceU8),
98+
Docs: sc.Sequence[sc.Str]{""},
99+
},
100+
types.RuntimeApiMethodMetadata{
101+
Name: "slot_duration",
102+
Inputs: sc.Sequence[types.RuntimeApiMethodParamMetadata]{},
103+
Output: sc.ToCompact(metadata.PrimitiveTypesU64),
104+
Docs: sc.Sequence[sc.Str]{},
105+
},
106+
},
107+
Docs: sc.Sequence[sc.Str]{" The API to query account nonce."},
108+
}
109+
110+
assert.Equal(t, expect, target.Metadata())
111+
}

api/block_builder/module.go

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package blockbuilder
33
import (
44
"bytes"
55

6+
sc "github.com/LimeChain/goscale"
7+
"github.com/LimeChain/gosemble/constants/metadata"
68
"github.com/LimeChain/gosemble/execution/extrinsic"
79
"github.com/LimeChain/gosemble/execution/types"
810
"github.com/LimeChain/gosemble/frame/executive"
@@ -80,7 +82,7 @@ func (m Module) ApplyExtrinsic(dataPtr int32, dataLen int32) int64 {
8082
}
8183

8284
buffer.Reset()
83-
applyExtrinsicResult.Encode(buffer)
85+
applyExtrinsicResult.Encode(buffer) // TODO: handle err
8486

8587
return m.memUtils.BytesToOffsetAndSize(buffer.Bytes())
8688
}
@@ -146,3 +148,60 @@ func (m Module) CheckInherents(dataPtr int32, dataLen int32) int64 {
146148

147149
return m.memUtils.BytesToOffsetAndSize(result.Bytes())
148150
}
151+
152+
func (m Module) Metadata() primitives.RuntimeApiMetadata {
153+
methods := sc.Sequence[primitives.RuntimeApiMethodMetadata]{
154+
primitives.RuntimeApiMethodMetadata{
155+
Name: "apply_extrinsic",
156+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{
157+
primitives.RuntimeApiMethodParamMetadata{
158+
Name: "Extrinsic",
159+
Type: sc.ToCompact(metadata.UncheckedExtrinsic),
160+
},
161+
},
162+
Output: sc.ToCompact(metadata.TypesResult),
163+
Docs: sc.Sequence[sc.Str]{" Apply the given extrinsic.",
164+
"",
165+
" Returns an inclusion outcome which specifies if this extrinsic is included in",
166+
" this block or not."},
167+
},
168+
primitives.RuntimeApiMethodMetadata{
169+
Name: "finalize_block",
170+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{},
171+
Output: sc.ToCompact(metadata.Header),
172+
Docs: sc.Sequence[sc.Str]{" Finish the current block."},
173+
},
174+
primitives.RuntimeApiMethodMetadata{
175+
Name: "inherent_extrinsics",
176+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{
177+
primitives.RuntimeApiMethodParamMetadata{
178+
Name: "inherent",
179+
Type: sc.ToCompact(metadata.TypesInherentData),
180+
},
181+
},
182+
Output: sc.ToCompact(metadata.TypesSequenceUncheckedExtrinsics),
183+
Docs: sc.Sequence[sc.Str]{" Generate inherent extrinsics. The inherent data will vary from chain to chain."},
184+
},
185+
primitives.RuntimeApiMethodMetadata{
186+
Name: "check_inherents",
187+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{
188+
primitives.RuntimeApiMethodParamMetadata{
189+
Name: "block",
190+
Type: sc.ToCompact(metadata.TypesBlock),
191+
},
192+
primitives.RuntimeApiMethodParamMetadata{
193+
Name: "data",
194+
Type: sc.ToCompact(metadata.TypesInherentData),
195+
},
196+
},
197+
Output: sc.ToCompact(metadata.CheckInherentsResult),
198+
Docs: sc.Sequence[sc.Str]{" Check that the inherents are valid. The inherent data will vary from chain to chain."},
199+
},
200+
}
201+
202+
return primitives.RuntimeApiMetadata{
203+
Name: ApiModuleName,
204+
Methods: methods,
205+
Docs: sc.Sequence[sc.Str]{" The `BlockBuilder` api trait that provides the required functionality for building a block."},
206+
}
207+
}

api/block_builder/module_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/ChainSafe/gossamer/lib/common"
99
sc "github.com/LimeChain/goscale"
10+
"github.com/LimeChain/gosemble/constants/metadata"
1011
"github.com/LimeChain/gosemble/execution/types"
1112
"github.com/LimeChain/gosemble/mocks"
1213
primitives "github.com/LimeChain/gosemble/primitives/types"
@@ -203,6 +204,65 @@ func Test_Module_CheckInherents_InvalidInherentData(t *testing.T) {
203204
mockMemoryUtils.AssertNotCalled(t, "BytesToOffsetAndSize", mock.Anything)
204205
}
205206

207+
func Test_Module_Metadata(t *testing.T) {
208+
target := setup()
209+
210+
expect := primitives.RuntimeApiMetadata{
211+
Name: ApiModuleName,
212+
Methods: sc.Sequence[primitives.RuntimeApiMethodMetadata]{
213+
primitives.RuntimeApiMethodMetadata{
214+
Name: "apply_extrinsic",
215+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{
216+
primitives.RuntimeApiMethodParamMetadata{
217+
Name: "Extrinsic",
218+
Type: sc.ToCompact(metadata.UncheckedExtrinsic),
219+
},
220+
},
221+
Output: sc.ToCompact(metadata.TypesResult),
222+
Docs: sc.Sequence[sc.Str]{" Apply the given extrinsic.",
223+
"",
224+
" Returns an inclusion outcome which specifies if this extrinsic is included in",
225+
" this block or not."},
226+
},
227+
primitives.RuntimeApiMethodMetadata{
228+
Name: "finalize_block",
229+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{},
230+
Output: sc.ToCompact(metadata.Header),
231+
Docs: sc.Sequence[sc.Str]{" Finish the current block."},
232+
},
233+
primitives.RuntimeApiMethodMetadata{
234+
Name: "inherent_extrinsics",
235+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{
236+
primitives.RuntimeApiMethodParamMetadata{
237+
Name: "inherent",
238+
Type: sc.ToCompact(metadata.TypesInherentData),
239+
},
240+
},
241+
Output: sc.ToCompact(metadata.TypesSequenceUncheckedExtrinsics),
242+
Docs: sc.Sequence[sc.Str]{" Generate inherent extrinsics. The inherent data will vary from chain to chain."},
243+
},
244+
primitives.RuntimeApiMethodMetadata{
245+
Name: "check_inherents",
246+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{
247+
primitives.RuntimeApiMethodParamMetadata{
248+
Name: "block",
249+
Type: sc.ToCompact(metadata.TypesBlock),
250+
},
251+
primitives.RuntimeApiMethodParamMetadata{
252+
Name: "data",
253+
Type: sc.ToCompact(metadata.TypesInherentData),
254+
},
255+
},
256+
Output: sc.ToCompact(metadata.CheckInherentsResult),
257+
Docs: sc.Sequence[sc.Str]{" Check that the inherents are valid. The inherent data will vary from chain to chain."},
258+
},
259+
},
260+
Docs: sc.Sequence[sc.Str]{" The `BlockBuilder` api trait that provides the required functionality for building a block."},
261+
}
262+
263+
assert.Equal(t, expect, target.Metadata())
264+
}
265+
206266
func setup() Module {
207267
mockExecutive = new(mocks.Executive)
208268
mockRuntimeDecoder = new(mocks.RuntimeDecoder)

api/core/module.go

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package core
33
import (
44
"bytes"
55

6+
sc "github.com/LimeChain/goscale"
7+
"github.com/LimeChain/gosemble/constants/metadata"
68
"github.com/LimeChain/gosemble/execution/types"
79
"github.com/LimeChain/gosemble/frame/executive"
810
"github.com/LimeChain/gosemble/primitives/hashing"
@@ -51,7 +53,7 @@ func (m Module) Item() primitives.ApiItem {
5153
// [Specification](https://spec.polkadot.network/#defn-rt-core-version)
5254
func (m Module) Version() int64 {
5355
buffer := &bytes.Buffer{}
54-
m.runtimeVersion.Encode(buffer)
56+
m.runtimeVersion.Encode(buffer) // TODO: handle err
5557
return m.memUtils.BytesToOffsetAndSize(buffer.Bytes())
5658
}
5759

@@ -68,7 +70,7 @@ func (m Module) InitializeBlock(dataPtr int32, dataLen int32) {
6870
if err != nil {
6971
log.Critical(err.Error())
7072
}
71-
m.executive.InitializeBlock(header)
73+
m.executive.InitializeBlock(header) // TODO: handle err
7274
}
7375

7476
// ExecuteBlock executes the provided block.
@@ -84,5 +86,44 @@ func (m Module) ExecuteBlock(dataPtr int32, dataLen int32) {
8486
if err != nil {
8587
log.Critical(err.Error())
8688
}
87-
m.executive.ExecuteBlock(block)
89+
m.executive.ExecuteBlock(block) // TODO: handle err
90+
}
91+
92+
func (m Module) Metadata() primitives.RuntimeApiMetadata {
93+
methods := sc.Sequence[primitives.RuntimeApiMethodMetadata]{
94+
primitives.RuntimeApiMethodMetadata{
95+
Name: "version",
96+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{},
97+
Output: sc.ToCompact(metadata.TypesRuntimeVersion),
98+
Docs: sc.Sequence[sc.Str]{" Returns the version of the runtime."},
99+
},
100+
primitives.RuntimeApiMethodMetadata{
101+
Name: "execute_block",
102+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{
103+
primitives.RuntimeApiMethodParamMetadata{
104+
Name: "block",
105+
Type: sc.ToCompact(metadata.TypesBlock),
106+
},
107+
},
108+
Output: sc.ToCompact(metadata.TypesEmptyTuple),
109+
Docs: sc.Sequence[sc.Str]{" Execute the given block."},
110+
},
111+
primitives.RuntimeApiMethodMetadata{
112+
Name: "initialize_block",
113+
Inputs: sc.Sequence[primitives.RuntimeApiMethodParamMetadata]{
114+
primitives.RuntimeApiMethodParamMetadata{
115+
Name: "header",
116+
Type: sc.ToCompact(metadata.Header),
117+
},
118+
},
119+
Output: sc.ToCompact(metadata.TypesEmptyTuple),
120+
Docs: sc.Sequence[sc.Str]{" Initialize a block with the given header."},
121+
},
122+
}
123+
124+
return primitives.RuntimeApiMetadata{
125+
Name: ApiModuleName,
126+
Methods: methods,
127+
Docs: sc.Sequence[sc.Str]{" The `Core` runtime api that every Substrate runtime needs to implement."},
128+
}
88129
}

0 commit comments

Comments
 (0)