Skip to content

Commit

Permalink
Merge pull request #68 from novasamatech/develop
Browse files Browse the repository at this point in the history
v1.10.0
  • Loading branch information
valentunn authored Dec 6, 2023
2 parents da027e7 + c510dca commit b640fc7
Show file tree
Hide file tree
Showing 13 changed files with 319 additions and 22 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
buildscript {
ext {
// App version
versionName = '1.9.1'
versionName = '1.10.0'
versionCode = 1

// SDK and tools
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@ fun v14Preset() = typePreset {

type(GenericCall)
type(GenericEvent)
type(EraType)

type(Data(this))
type(GenericAccountId)

alias("Balance", "u128")
}

fun v13Preset(): TypePreset = typePreset {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ class Alias(alias: String, val aliasedReference: TypeReference) : Type<Any?>(ali
fun RuntimeType<*, *>.aliasedAs(newName: String): Alias {
return Alias(newName, TypeReference(this))
}

fun TypeReference.aliasedAs(newName: String): Alias {
return Alias(newName, this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.DictEn
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.generics.MULTI_ADDRESS_ID
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.primitives.FixedByteArray

private const val ADDRESS_TYPE = "Address"

object AddressInstanceConstructor : RuntimeType.InstanceConstructor<AccountId> {

override fun constructInstance(typeRegistry: TypeRegistry, value: AccountId): Any {
return when (val addressType = typeRegistry.getOrThrow(ADDRESS_TYPE)) {
return when (val addressType = typeRegistry.getOrThrow(ExtrinsicTypes.ADDRESS)) {
is DictEnum -> { // MultiAddress
DictEnum.Entry(MULTI_ADDRESS_ID, value)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package jp.co.soramitsu.fearless_utils.runtime.definitions.types.instances

object ExtrinsicTypes {

const val ADDRESS = "Address"
const val SIGNATURE = "ExtrinsicSignature"
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.DictEn
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.Struct
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.generics.MultiSignature
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.generics.prepareForEncoding

private const val EXTRINSIC_SIGNATURE_TYPE = "ExtrinsicSignature"
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.primitives.FixedByteArray
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.skipAliases

object SignatureInstanceConstructor : RuntimeType.InstanceConstructor<SignatureWrapper> {

override fun constructInstance(typeRegistry: TypeRegistry, value: SignatureWrapper): Any {
return when (val type = typeRegistry.getOrThrow(EXTRINSIC_SIGNATURE_TYPE)) {
return when (val type = typeRegistry.getOrThrow(ExtrinsicTypes.SIGNATURE).skipAliases()) {
is DictEnum -> { // MultiSignature
MultiSignature(value.encryptionType, value.signature).prepareForEncoding()
}
Expand All @@ -32,7 +32,9 @@ object SignatureInstanceConstructor : RuntimeType.InstanceConstructor<SignatureW

Struct.Instance(fields)
}
else -> throw UnsupportedOperationException("Unknown signature type: ${type.name}")
is FixedByteArray -> value.signature

else -> throw UnsupportedOperationException("Unknown signature type: ${type?.name}")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package jp.co.soramitsu.fearless_utils.runtime.definitions.v14.typeMapping

import jp.co.soramitsu.fearless_utils.runtime.definitions.registry.TypePresetBuilder
import jp.co.soramitsu.fearless_utils.runtime.definitions.registry.alias
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.Type
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.instances.ExtrinsicTypes
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.PortableType
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.paramType
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.type
import jp.co.soramitsu.fearless_utils.scale.EncodableStruct

private const val UNCHECKED_EXTRINSIC_TYPE = "sp_runtime.generic.unchecked_extrinsic.UncheckedExtrinsic"

class AddExtrinsicTypesSiTypeMapping : SiTypeMapping {

override fun map(
originalDefinition: EncodableStruct<PortableType>,
suggestedTypeName: String,
typesBuilder: TypePresetBuilder
): Type<*>? {
if (suggestedTypeName == UNCHECKED_EXTRINSIC_TYPE) {
addTypeFromTypeParams(
originalDefinition = originalDefinition,
typesBuilder = typesBuilder,
typeParamName = "Address",
newTypeName = ExtrinsicTypes.ADDRESS
)

addTypeFromTypeParams(
originalDefinition = originalDefinition,
typesBuilder = typesBuilder,
typeParamName = "Signature",
newTypeName = ExtrinsicTypes.SIGNATURE
)
}

// we don't modify any existing type
return null
}

private fun addTypeFromTypeParams(
originalDefinition: EncodableStruct<PortableType>,
typesBuilder: TypePresetBuilder,
typeParamName: String,
newTypeName: String
) {
val paramType = originalDefinition.type.paramType(typeParamName) ?: return

// type with type-id name is present in the registry as alias to fully qualified name
typesBuilder.alias(newTypeName, paramType.toString())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package jp.co.soramitsu.fearless_utils.runtime.definitions.v14.typeMapping

import jp.co.soramitsu.fearless_utils.runtime.definitions.registry.TypePresetBuilder
import jp.co.soramitsu.fearless_utils.runtime.definitions.registry.getOrCreate
import jp.co.soramitsu.fearless_utils.runtime.definitions.registry.type
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.Type
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.TypeReference
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.Struct
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.PortableType
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.TypeDefComposite
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.asCompositeOrNull
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.fieldType
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.type
import jp.co.soramitsu.fearless_utils.scale.EncodableStruct

private const val DISPATCH_INFO_TYPE = "frame_support.dispatch.DispatchInfo"

class AddRuntimeDispatchInfoSiTypeMapping : SiTypeMapping {

override fun map(
originalDefinition: EncodableStruct<PortableType>,
suggestedTypeName: String,
typesBuilder: TypePresetBuilder
): Type<*>? {
if (suggestedTypeName == DISPATCH_INFO_TYPE) {
addRuntimeDispatchInfo(originalDefinition, typesBuilder)
}

// we don't modify any existing type
return null
}

private fun addRuntimeDispatchInfo(
dispatchInfoType: EncodableStruct<PortableType>,
typesBuilder: TypePresetBuilder
) {
val typeDef = dispatchInfoType.type.asCompositeOrNull() ?: return

val weightType = typeDef.fieldTypeReference("weight", typesBuilder) ?: return
val dispatchClassType = typeDef.fieldTypeReference("class", typesBuilder) ?: return
val partialFeeType = typesBuilder.getOrCreate("u128")

val runtimeDispatchInfo = RuntimeDispatchInfo(weightType, dispatchClassType, partialFeeType)

typesBuilder.type(runtimeDispatchInfo)
}

private fun EncodableStruct<TypeDefComposite>.fieldTypeReference(
name: String,
typesBuilder: TypePresetBuilder
): TypeReference? {
val fieldType = fieldType(name) ?: return null

return typesBuilder.getOrCreate(fieldType.toString())
}
}

fun RuntimeDispatchInfo(
weightType: TypeReference,
classType: TypeReference,
partialFeeType: TypeReference
) = Struct(
name = "RuntimeDispatchInfo",
mapping = linkedMapOf(
"weight" to weightType,
"class" to classType,
"partialFee" to partialFeeType
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package jp.co.soramitsu.fearless_utils.runtime.definitions.v14.typeMapping

import jp.co.soramitsu.fearless_utils.extensions.tryFindNonNull
import jp.co.soramitsu.fearless_utils.runtime.definitions.registry.TypePresetBuilder
import jp.co.soramitsu.fearless_utils.runtime.definitions.registry.getOrCreate
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.RuntimeType
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.Type
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.aliasedAs
import jp.co.soramitsu.fearless_utils.runtime.definitions.v14.typeMapping.PathMatchTypeMapping.Matcher
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.PortableType
import jp.co.soramitsu.fearless_utils.scale.EncodableStruct

typealias PathMatchTypeMappingReplacement<T> = Pair<T, PathMatchTypeMapping.Replacement>

class PathMatchTypeMapping(
private val replacements: List<PathMatchTypeMappingReplacement<Matcher>>,
) : SiTypeMapping {

sealed class Replacement {

abstract fun create(suggestedName: String, types: TypePresetBuilder): RuntimeType<*, *>

class AliasTo(private val aliasedName: String) : Replacement() {

override fun create(
suggestedName: String,
types: TypePresetBuilder
): RuntimeType<*, *> {
return types.getOrCreate(aliasedName).aliasedAs(suggestedName)
}
}

class CreateType(
private val createExpr: (suggestedName: String, types: TypePresetBuilder) -> RuntimeType<*, *>
) : Replacement() {

override fun create(
suggestedName: String,
types: TypePresetBuilder
): RuntimeType<*, *> {
return createExpr(suggestedName, types)
}
}
}

sealed class Matcher {

abstract fun match(fullPathName: String): Boolean

class Exact(val value: String) : Matcher() {
override fun match(fullPathName: String): Boolean {
return value == fullPathName
}
}

class PrefixMatch(val prefix: String) : Matcher() {
override fun match(fullPathName: String): Boolean {
return fullPathName.startsWith(prefix)
}
}

class SuffixMatch(val suffix: String) : Matcher() {
override fun match(fullPathName: String): Boolean {
return fullPathName.endsWith(suffix)
}
}
}

override fun map(
originalDefinition: EncodableStruct<PortableType>,
suggestedTypeName: String,
typesBuilder: TypePresetBuilder
): Type<*>? {
return replacements.tryFindNonNull { (matcher, replacement) ->
if (matcher.match(suggestedTypeName)) {
replacement.create(suggestedTypeName, typesBuilder)
} else {
null
}
}
}
}

/**
* Can be used to pass wildcard strings instead of [Matcher] instances
*
* "full.name" -> Matcher.Exact("full.name")
* "*suffix.name" -> Matcher.Suffix("suffix.name")
* "prefix.name*" -> Matcher.Prefix("prefix.name)
*
* Wildcards are only considered at the beginning or at the end of the string,
* others will be considered as a part of the content
*/
fun PathMatchTypeMapping(
vararg replacements: PathMatchTypeMappingReplacement<String>
): PathMatchTypeMapping {
val replacementMatchers = replacements.map { (wildCardString, typeCreator) ->
Matcher(wildCardString) to typeCreator
}

return PathMatchTypeMapping(replacementMatchers)
}

private fun Matcher(wildCardString: String): Matcher {
return when {
wildCardString.startsWith("*") -> Matcher.SuffixMatch(wildCardString.drop(1))
wildCardString.endsWith("*") -> Matcher.PrefixMatch(wildCardString.dropLast(1))
else -> Matcher.Exact(wildCardString)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.Alias
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.Option
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.SetType
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.composite.aliasedAs
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.generics.EraType
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.primitives.DynamicByteArray
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.primitives.FixedByteArray
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.primitives.u8
import jp.co.soramitsu.fearless_utils.runtime.definitions.types.skipAliases
import jp.co.soramitsu.fearless_utils.runtime.definitions.v14.typeMapping.PathMatchTypeMapping.Replacement.AliasTo
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.PortableType
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.RegistryType
import jp.co.soramitsu.fearless_utils.runtime.metadata.v14.TypeDefArray
Expand Down Expand Up @@ -173,18 +173,11 @@ object SiByteArrayMapping : SiTypeMapping {
}
}

@Deprecated("Use PathMatchTypeMapping instead")
class ReplaceTypesSiTypeMapping(
vararg cases: Pair<String, Type<*>>
) : SiTypeMapping {

companion object {
fun default(): SiTypeMapping {
return ReplaceTypesSiTypeMapping(
"sp_runtime.generic.era.Era" to EraType
)
}
}

private val casesById = cases.toMap()

override fun map(
Expand All @@ -199,15 +192,32 @@ class ReplaceTypesSiTypeMapping(
fun SiTypeMapping.Companion.default(): OneOfSiTypeMapping {
return OneOfSiTypeMapping(
listOf(
AddExtrinsicTypesSiTypeMapping(),
AddRuntimeDispatchInfoSiTypeMapping(),
SiByteArrayMapping,
SiOptionTypeMapping,
SiSetTypeMapping,
SiCompositeNoneToAliasTypeMapping,
ReplaceTypesSiTypeMapping.default(),
knownReplacements(),
)
)
}

private fun knownReplacements(): PathMatchTypeMapping {
val callAlias = AliasTo("GenericCall")
val eventAlias = AliasTo("GenericEvent")

return PathMatchTypeMapping(
"*_runtime.RuntimeCall" to callAlias,
"*_runtime.Call" to callAlias,
"*_runtime.RuntimeEvent" to eventAlias,
"*_runtime.Event" to eventAlias,

"pallet_identity.types.Data" to AliasTo("Data"),
"sp_runtime.generic.era.Era" to AliasTo("Era")
)
}

operator fun OneOfSiTypeMapping.plus(other: SiTypeMapping): OneOfSiTypeMapping {
return OneOfSiTypeMapping(listOf(other) + inner)
}
Expand Down
Loading

0 comments on commit b640fc7

Please sign in to comment.