-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
384 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
274 changes: 274 additions & 0 deletions
274
SubstrateSdk/Classes/Runtime/RuntimeAugmentation/RuntimeAugmentationFactory.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
import Foundation | ||
|
||
public protocol RuntimeAugmentationFactoryProtocol: AnyObject { | ||
func createSubstrateAugmentation(for runtime: RuntimeMetadataV14) -> RuntimeAugmentationResult | ||
func createEthereumBasedAugmentation(for runtime: RuntimeMetadataV14) -> RuntimeAugmentationResult | ||
} | ||
|
||
public final class RuntimeAugmentationFactory: RuntimeAugmentationFactoryProtocol { | ||
static let uncheckedExtrinsicModuleName = "sp_runtime.UncheckedExtrinsic" | ||
|
||
public init() {} | ||
|
||
private func addingAdditionalOneOfTo( | ||
types: [String], | ||
fromType: String, | ||
additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14, | ||
mode: RuntimeTypeMatchingMode | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
for type in types { | ||
if let metadataType = RuntimeMetadataSearchEngine.find(type: type, in: runtime, mode: mode) { | ||
let node = AliasNode(typeName: fromType, underlyingTypeName: metadataType) | ||
return additionalNodes.adding(node: node) | ||
} | ||
} | ||
|
||
return additionalNodes.adding(notMatchedType: fromType) | ||
} | ||
|
||
private func addingAdditionalOneOfFrom( | ||
types: [String], | ||
toType: String, | ||
additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14, | ||
mode: RuntimeTypeMatchingMode | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
for type in types { | ||
if let metadataType = RuntimeMetadataSearchEngine.find(type: type, in: runtime, mode: mode) { | ||
let node = AliasNode(typeName: metadataType, underlyingTypeName: toType) | ||
return additionalNodes.adding(node: node) | ||
} | ||
} | ||
|
||
return additionalNodes.adding(notMatchedType: toType) | ||
} | ||
|
||
private func addingEventPhaseNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
addingAdditionalOneOfTo( | ||
types: ["frame_system.Phase"], | ||
fromType: KnownType.phase.name, | ||
additionalNodes: additionalNodes, | ||
runtime: runtime, | ||
mode: .firstLastComponents | ||
) | ||
} | ||
|
||
private func addingSubstrateAddressNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
if let addressType = RuntimeMetadataSearchEngine.findParameterType( | ||
for: Self.uncheckedExtrinsicModuleName, | ||
parameterName: "Address", | ||
in: runtime, | ||
mode: .firstLastComponents | ||
) { | ||
let node = AliasNode(typeName: KnownType.address.name, underlyingTypeName: addressType) | ||
return additionalNodes.adding(node: node) | ||
} else { | ||
return additionalNodes.adding(notMatchedType: KnownType.address.name) | ||
} | ||
} | ||
|
||
private func addingEthereumBasedAddressNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
addingAdditionalOneOfTo( | ||
types: ["AccountId20"], | ||
fromType: KnownType.address.name, | ||
additionalNodes: additionalNodes, | ||
runtime: runtime, | ||
mode: .lastComponent | ||
) | ||
} | ||
|
||
private func addingSubstrateSignatureNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
if let signatureType = RuntimeMetadataSearchEngine.findParameterType( | ||
for: Self.uncheckedExtrinsicModuleName, | ||
parameterName: "Signature", | ||
in: runtime, | ||
mode: .firstLastComponents | ||
) { | ||
let node = AliasNode(typeName: KnownType.signature.name, underlyingTypeName: signatureType) | ||
return additionalNodes.adding(node: node) | ||
} else { | ||
return additionalNodes.adding(notMatchedType: KnownType.signature.name) | ||
} | ||
} | ||
|
||
private func addingEthereumBasedSignatureNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime _: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
let node = StructNode( | ||
typeName: KnownType.signature.name, | ||
typeMapping: [ | ||
NameNode(name: "r", node: ProxyNode(typeName: GenericType.h256.name)), | ||
NameNode(name: "s", node: ProxyNode(typeName: GenericType.h256.name)), | ||
NameNode(name: "v", node: ProxyNode(typeName: PrimitiveType.u8.name)) | ||
] | ||
) | ||
|
||
return additionalNodes.adding(node: node) | ||
} | ||
|
||
private func addingSubstrateAccountIdNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
addingAdditionalOneOfFrom( | ||
types: ["AccountId32"], | ||
toType: GenericType.accountId.name, | ||
additionalNodes: additionalNodes, | ||
runtime: runtime, | ||
mode: .lastComponent | ||
) | ||
} | ||
|
||
private func addingPalletIdentityDataNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
addingAdditionalOneOfFrom( | ||
types: ["pallet_identity.Data"], | ||
toType: GenericType.data.name, | ||
additionalNodes: additionalNodes, | ||
runtime: runtime, | ||
mode: .firstLastComponents | ||
) | ||
} | ||
|
||
private func addingRuntimeEventNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
addingAdditionalOneOfFrom( | ||
types: ["RuntimeEvent", "Event"], | ||
toType: GenericType.event.name, | ||
additionalNodes: additionalNodes, | ||
runtime: runtime, | ||
mode: .lastComponent | ||
) | ||
} | ||
|
||
private func addingRuntimeCallNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
addingAdditionalOneOfFrom( | ||
types: ["RuntimeCall", "Call"], | ||
toType: GenericType.call.name, | ||
additionalNodes: additionalNodes, | ||
runtime: runtime, | ||
mode: .lastComponent | ||
) | ||
} | ||
|
||
private func addingRuntimeDispatchNode( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
let feeType = KnownType.runtimeDispatchInfo.name | ||
let runtimeType = "frame_support.dispatch.DispatchInfo" | ||
|
||
guard | ||
let portableType = RuntimeMetadataSearchEngine.findPortableType( | ||
for: runtimeType, | ||
in: runtime, | ||
mode: .firstLastComponents | ||
), | ||
case let .composite(compositeType) = portableType.type.typeDefinition else { | ||
return additionalNodes.adding(notMatchedType: feeType) | ||
} | ||
|
||
guard | ||
let weightLookupId = compositeType.fields.first(where: { $0.name == "weight" })?.type, | ||
let weightType = runtime.types.types.first( | ||
where: { $0.identifier == weightLookupId } | ||
)?.type.pathBasedName, | ||
let dispatchClassLookupId = compositeType.fields.first(where: { $0.name == "class" })?.type, | ||
let dispatchClassType = runtime.types.types.first( | ||
where: { $0.identifier == dispatchClassLookupId } | ||
)?.type.pathBasedName else { | ||
return additionalNodes.adding(notMatchedType: feeType) | ||
} | ||
|
||
let node = StructNode( | ||
typeName: feeType, | ||
typeMapping: [ | ||
NameNode(name: "weight", node: ProxyNode(typeName: weightType)), | ||
NameNode(name: "class", node: ProxyNode(typeName: dispatchClassType)), | ||
NameNode(name: "partialFee", node: ProxyNode(typeName: PrimitiveType.u128.name)) | ||
] | ||
) | ||
|
||
return additionalNodes.adding(node: node) | ||
} | ||
|
||
private func getCommonAdditionalNodes( | ||
for runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
var additionalNodes = RuntimeAugmentationResult.AdditionalNodes( | ||
nodes: [ | ||
AliasNode(typeName: KnownType.balance.name, underlyingTypeName: PrimitiveType.u128.name), | ||
AliasNode(typeName: KnownType.index.name, underlyingTypeName: PrimitiveType.u32.name) | ||
], | ||
notMatch: [] | ||
) | ||
|
||
additionalNodes = addingEventPhaseNode(to: additionalNodes, runtime: runtime) | ||
additionalNodes = addingRuntimeEventNode(to: additionalNodes, runtime: runtime) | ||
additionalNodes = addingRuntimeCallNode(to: additionalNodes, runtime: runtime) | ||
additionalNodes = addingSubstrateAccountIdNode(to: additionalNodes, runtime: runtime) | ||
additionalNodes = addingPalletIdentityDataNode(to: additionalNodes, runtime: runtime) | ||
additionalNodes = addingRuntimeDispatchNode(to: additionalNodes, runtime: runtime) | ||
|
||
return additionalNodes | ||
} | ||
|
||
private func addingSubstrateSpecificNodes( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
var updatedNodes = additionalNodes | ||
updatedNodes = addingSubstrateAddressNode(to: updatedNodes, runtime: runtime) | ||
updatedNodes = addingSubstrateSignatureNode(to: updatedNodes, runtime: runtime) | ||
|
||
return updatedNodes | ||
} | ||
|
||
private func addingEthereumBasedSpecificNodes( | ||
to additionalNodes: RuntimeAugmentationResult.AdditionalNodes, | ||
runtime: RuntimeMetadataV14 | ||
) -> RuntimeAugmentationResult.AdditionalNodes { | ||
var updatedNodes = additionalNodes | ||
updatedNodes = addingEthereumBasedAddressNode(to: updatedNodes, runtime: runtime) | ||
updatedNodes = addingEthereumBasedSignatureNode(to: updatedNodes, runtime: runtime) | ||
|
||
return updatedNodes | ||
} | ||
} | ||
|
||
extension RuntimeAugmentationFactory { | ||
public func createSubstrateAugmentation(for runtime: RuntimeMetadataV14) -> RuntimeAugmentationResult { | ||
var additionalNodes = getCommonAdditionalNodes(for: runtime) | ||
additionalNodes = addingSubstrateSpecificNodes(to: additionalNodes, runtime: runtime) | ||
|
||
return RuntimeAugmentationResult(additionalNodes: additionalNodes) | ||
} | ||
|
||
public func createEthereumBasedAugmentation(for runtime: RuntimeMetadataV14) -> RuntimeAugmentationResult { | ||
var additionalNodes = getCommonAdditionalNodes(for: runtime) | ||
additionalNodes = addingEthereumBasedSpecificNodes(to: additionalNodes, runtime: runtime) | ||
|
||
return RuntimeAugmentationResult(additionalNodes: additionalNodes) | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
SubstrateSdk/Classes/Runtime/RuntimeAugmentation/RuntimeAugmentationResult.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import Foundation | ||
|
||
public struct RuntimeAugmentationResult { | ||
public struct AdditionalNodes { | ||
public let nodes: [Node] | ||
public let notMatch: Set<String> | ||
|
||
public init(nodes: [Node], notMatch: Set<String>) { | ||
self.nodes = nodes | ||
self.notMatch = notMatch | ||
} | ||
|
||
public func adding(node: Node) -> AdditionalNodes { | ||
.init(nodes: nodes + [node], notMatch: notMatch) | ||
} | ||
|
||
public func adding(notMatchedType: String) -> AdditionalNodes { | ||
.init(nodes: nodes, notMatch: notMatch.union([notMatchedType])) | ||
} | ||
} | ||
|
||
public let additionalNodes: AdditionalNodes | ||
} |
Oops, something went wrong.