Skip to content

Commit

Permalink
added identifiable. validatable refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
ypopovych committed Sep 3, 2023
1 parent f687317 commit be4f43d
Show file tree
Hide file tree
Showing 74 changed files with 2,634 additions and 1,403 deletions.
24 changes: 18 additions & 6 deletions Sources/Substrate/Api/ConstantsApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,24 +76,36 @@ public extension ConstantsApiRegistry {
}
}

public protocol StaticConstant: PalletType {
public protocol StaticConstant: FrameType {
associatedtype TValue
static var pallet: String { get }
static func decode<D: ScaleCodec.Decoder>(valueFrom decoder: inout D, runtime: any Runtime) throws -> TValue
}

public extension StaticConstant {
@inlinable static var frame: String { pallet }
}

public extension StaticConstant where TValue: RuntimeDecodable {
static func decode<D: ScaleCodec.Decoder>(valueFrom decoder: inout D, runtime: any Runtime) throws -> TValue {
try TValue(from: &decoder, runtime: runtime)
}
}

public extension StaticConstant where Self: RuntimeValidatable, TValue: RuntimeDynamicValidatable {
static func validate(runtime: any Runtime) -> Result<Void, ValidationError> {
public extension StaticConstant where TValue: ValidatableType {
static func validate(runtime: any Runtime) -> Result<Void, FrameTypeError> {
guard let info = runtime.resolve(constant: name, pallet: pallet) else {
return .failure(.infoNotFound(for: Self.self))
return .failure(.typeInfoNotFound(for: Self.self))
}
return TValue.validate(runtime: runtime, type: info.type.id).mapError {
.childError(for: Self.self, error: $0)
return TValue.validate(runtime: runtime, type: info.type).mapError {
.childError(for: Self.self, index: -1, error: $0)
}
}
}

public extension StaticConstant where TValue: IdentifiableType {
@inlinable
static var definition: FrameTypeDefinition {
.constant(Self.self, type: TValue.definition)
}
}
54 changes: 30 additions & 24 deletions Sources/Substrate/Block/Event.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,32 @@ public protocol Event: RuntimeDynamicDecodable {
var name: String { get }
}

public protocol IdentifiableEvent: Event, PalletType {}
public protocol PalletEvent: Event, FrameType {
static var pallet: String { get }
}

public extension PalletEvent {
@inlinable var pallet: String { Self.pallet }
@inlinable var frame: String { pallet }
@inlinable static var frame: String { pallet }
@inlinable static var frameTypeName: String { "Event" }
}

public typealias EventTypeInfo = [(field: NetworkType.Field, type: NetworkType)]
public typealias EventChildTypes = [ValidatableType.Type]

public extension PalletEvent where
Self: ComplexFrameType, TypeInfo == EventTypeInfo
{
static func typeInfo(runtime: any Runtime) -> Result<TypeInfo, FrameTypeError> {
guard let info = runtime.resolve(eventParams: name, pallet: pallet) else {
return .failure(.typeInfoNotFound(for: Self.self))
}
return .success(info)
}
}

public protocol StaticEvent: IdentifiableEvent, RuntimeDecodable {
public protocol StaticEvent: PalletEvent, RuntimeDecodable {
init<D: ScaleCodec.Decoder>(paramsFrom decoder: inout D, runtime: Runtime) throws
}

Expand All @@ -24,35 +47,18 @@ public extension StaticEvent {
let modIndex = try decoder.decode(UInt8.self)
let evIndex = try decoder.decode(UInt8.self)
guard let info = runtime.resolve(eventName: evIndex, pallet: modIndex) else {
throw EventDecodingError.eventNotFound(index: evIndex, pallet: modIndex)
throw FrameTypeError.typeInfoNotFound(for: Self.self, index: evIndex, frame: modIndex)
}
guard Self.pallet == info.pallet && Self.name == info.name else {
throw EventDecodingError.foundWrongEvent(found: (name: info.name, pallet: info.pallet),
expected: (name: Self.name, pallet: Self.pallet))
guard Self.frame == info.pallet && Self.name == info.name else {
throw FrameTypeError.foundWrongType(for: Self.self, name: info.name, frame: info.pallet)
}
try self.init(paramsFrom: &decoder, runtime: runtime)
}
}

public extension IdentifiableEvent where Self: RuntimeValidatableComposite {
static func validatableFieldIds(runtime: any Runtime) -> Result<[NetworkType.Id], ValidationError> {
guard let info = runtime.resolve(eventParams: name, pallet: pallet) else {
return .failure(.infoNotFound(for: Self.self))
}
return .success(info.map{$0.type})
}
}

public protocol SomeEventRecord: RuntimeDynamicDecodable, RuntimeDynamicValidatable {
public protocol SomeEventRecord: RuntimeDynamicDecodable, ValidatableType {
var extrinsicIndex: UInt32? { get }
var header: (name: String, pallet: String) { get }
var any: AnyEvent { get throws }
func typed<E: IdentifiableEvent>(_ type: E.Type) throws -> E
}

public enum EventDecodingError: Error {
case eventNotFound(index: UInt8, pallet: UInt8)
case foundWrongEvent(found: (name: String, pallet: String), expected: (name: String, pallet: String))
case decodedNonVariantValue(Value<NetworkType.Id>)
case tooManyFieldsInVariant(variant: Value<NetworkType.Id>, expected: Int)
func typed<E: PalletEvent>(_ type: E.Type) throws -> E
}
30 changes: 15 additions & 15 deletions Sources/Substrate/Block/Events.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation
import ScaleCodec

public protocol SomeBlockEvents: RuntimeDynamicDecodable, RuntimeDynamicValidatable, Default {
public protocol SomeBlockEvents: RuntimeDynamicDecodable, ValidatableType, Default {
associatedtype ER: SomeEventRecord
var events: [ER] { get }
func events(extrinsic index: UInt32) -> [ER]
Expand All @@ -27,11 +27,11 @@ public extension SomeBlockEvents {
} != nil
}

func has<E: IdentifiableEvent>(_ type: E.Type) -> Bool {
func has<E: PalletEvent>(_ type: E.Type) -> Bool {
has(event: E.name, pallet: E.pallet)
}

func has<E: IdentifiableEvent>(_ type: E.Type, extrinsic index: UInt32) -> Bool {
func has<E: PalletEvent>(_ type: E.Type, extrinsic index: UInt32) -> Bool {
has(event: E.name, pallet: E.pallet, extrinsic: index)
}

Expand All @@ -47,11 +47,11 @@ public extension SomeBlockEvents {
}
}

func all<E: IdentifiableEvent>(records type: E.Type) -> [ER] {
func all<E: PalletEvent>(records type: E.Type) -> [ER] {
all(records: E.name, pallet: E.pallet)
}

func all<E: IdentifiableEvent>(records type: E.Type, extrinsic index: UInt32) -> [ER] {
func all<E: PalletEvent>(records type: E.Type, extrinsic index: UInt32) -> [ER] {
all(records: E.name, pallet: E.pallet, extrinsic: index)
}

Expand All @@ -63,11 +63,11 @@ public extension SomeBlockEvents {
try all(records: event, pallet: pallet, extrinsic: index).map { try $0.any }
}

func all<E: IdentifiableEvent>(events type: E.Type) throws -> [E] {
func all<E: PalletEvent>(events type: E.Type) throws -> [E] {
try all(records: E.name, pallet: E.pallet).map { try $0.typed(type) }
}

func all<E: IdentifiableEvent>(events type: E.Type, extrinsic index: UInt32) throws -> [E] {
func all<E: PalletEvent>(events type: E.Type, extrinsic index: UInt32) throws -> [E] {
try all(records: E.name, pallet: E.pallet, extrinsic: index).map { try $0.typed(type) }
}

Expand All @@ -83,11 +83,11 @@ public extension SomeBlockEvents {
}
}

func first<E: IdentifiableEvent>(record type: E.Type) -> ER? {
func first<E: PalletEvent>(record type: E.Type) -> ER? {
first(record: E.name, pallet: E.pallet)
}

func first<E: IdentifiableEvent>(record type: E.Type, extrinsic index: UInt32) -> ER? {
func first<E: PalletEvent>(record type: E.Type, extrinsic index: UInt32) -> ER? {
first(record: E.name, pallet: E.pallet, extrinsic: index)
}

Expand All @@ -99,11 +99,11 @@ public extension SomeBlockEvents {
try first(record: name, pallet: pallet, extrinsic: index).map{try $0.any}
}

func first<E: IdentifiableEvent>(event type: E.Type) throws -> E? {
func first<E: PalletEvent>(event type: E.Type) throws -> E? {
try first(record: type).map{try $0.typed(type)}
}

func first<E: IdentifiableEvent>(event type: E.Type, extrinsic index: UInt32) throws -> E? {
func first<E: PalletEvent>(event type: E.Type, extrinsic index: UInt32) throws -> E? {
try first(record: type, extrinsic: index).map{try $0.typed(type)}
}

Expand All @@ -119,11 +119,11 @@ public extension SomeBlockEvents {
}
}

func last<E: IdentifiableEvent>(record type: E.Type) -> ER? {
func last<E: PalletEvent>(record type: E.Type) -> ER? {
last(record: E.name, pallet: E.pallet)
}

func last<E: IdentifiableEvent>(record type: E.Type, extrinsic index: UInt32) -> ER? {
func last<E: PalletEvent>(record type: E.Type, extrinsic index: UInt32) -> ER? {
last(record: E.name, pallet: E.pallet, extrinsic: index)
}

Expand All @@ -135,11 +135,11 @@ public extension SomeBlockEvents {
try last(record: name, pallet: pallet, extrinsic: index).map{try $0.any}
}

func last<E: IdentifiableEvent>(event type: E.Type) throws -> E? {
func last<E: PalletEvent>(event type: E.Type) throws -> E? {
try last(record: type).map{try $0.typed(type)}
}

func last<E: IdentifiableEvent>(event type: E.Type, extrinsic index: UInt32) throws -> E? {
func last<E: PalletEvent>(event type: E.Type, extrinsic index: UInt32) throws -> E? {
try last(record: type, extrinsic: index).map{try $0.typed(type)}
}

Expand Down
28 changes: 14 additions & 14 deletions Sources/Substrate/Config/Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation
import ScaleCodec

public typealias ConfigUnsignedInteger = UnsignedInteger & ValueRepresentable & DataConvertible
& CompactCodable & Swift.Codable & RuntimeCodable & RuntimeDynamicValidatable
& CompactCodable & Swift.Codable & RuntimeCodable & IdentifiableType

// Config split to avoid recursive types
public protocol BasicConfig {
Expand All @@ -19,11 +19,11 @@ public protocol BasicConfig {
associatedtype TAddress: Address<TAccountId>
associatedtype TSignature: Signature
associatedtype TExtrinsicEra: SomeExtrinsicEra
associatedtype TExtrinsicPayment: ValueRepresentable & RuntimeDynamicValidatable
associatedtype TExtrinsicPayment: ValueRepresentable & ValidatableType
associatedtype TSystemProperties: SystemProperties
associatedtype TRuntimeVersion: RuntimeVersion
associatedtype TRuntimeDispatchInfo: RuntimeDynamicDecodable & RuntimeDynamicValidatable
associatedtype TFeeDetails: RuntimeDynamicDecodable & RuntimeDynamicValidatable
associatedtype TRuntimeDispatchInfo: RuntimeDynamicDecodable & ValidatableType
associatedtype TFeeDetails: RuntimeDynamicDecodable & ValidatableType
}

public protocol Config {
Expand Down Expand Up @@ -62,8 +62,8 @@ public protocol Config {
func extrinsicManager() throws -> TExtrinsicManager
func customCoders() throws -> [RuntimeCustomDynamicCoder]
// Return Config pallets list for validation
func pallets(runtime: any Runtime) throws -> [Pallet]
func runtimeCalls(runtime: any Runtime) throws -> [any (StaticRuntimeCall & RuntimeValidatable).Type]
func frames(runtime: any Runtime) throws -> [Frame]
func runtimeCalls(runtime: any Runtime) throws -> [any StaticRuntimeCall.Type]
// If you want your own Scale Codec coders
func encoder() -> ScaleCodec.Encoder
func encoder(reservedCapacity count: Int) -> ScaleCodec.Encoder
Expand All @@ -76,7 +76,7 @@ public protocol BatchSupportedConfig: Config {
associatedtype TBatchAllCall: SomeBatchCall

func isBatchSupported(metadata: any Metadata) -> Bool
func batchCalls(runtime: any Runtime) throws -> [SomeBatchCall.Type]
func batchCalls(runtime: any Runtime) throws -> [any SomeBatchCall.Type]
}

@frozen public struct SBT<C: BasicConfig> {
Expand Down Expand Up @@ -152,7 +152,7 @@ public extension BatchSupportedConfig {
metadata.resolve(pallet: TBatchAllCall.pallet)?.callIndex(name: TBatchAllCall.name) != nil
}

func batchCalls(runtime: any Runtime) throws -> [SomeBatchCall.Type] {
func batchCalls(runtime: any Runtime) throws -> [any SomeBatchCall.Type] {
[TBatchCall.self, TBatchAllCall.self]
}
}
Expand All @@ -166,14 +166,14 @@ public extension BatchSupportedConfig {
}

@inlinable
static func defaultPallets<C: Config>(runtime: any Runtime, config: C) throws -> [Pallet] {
try [BaseSystemPallet<C>(runtime: runtime, config: config)]
static func defaultFrames<C: Config>(runtime: any Runtime, config: C) throws -> [Frame] {
try [BaseSystemFrame<C>(runtime: runtime, config: config)]
}

@inlinable
static func defaultRuntimeCalls<C: Config>(
runtime: any Runtime, config: C
) -> [any (StaticRuntimeCall & RuntimeValidatable).Type] {
) -> [any StaticRuntimeCall.Type] {
[TransactionQueryInfoRuntimeCall<ST<C>.RuntimeDispatchInfo>.self,
TransactionQueryFeeDetailsRuntimeCall<ST<C>.FeeDetails>.self]
}
Expand Down Expand Up @@ -225,12 +225,12 @@ public extension Config {
}

@inlinable
func pallets(runtime: any Runtime) throws -> [Pallet] {
try Configs.defaultPallets(runtime: runtime, config: self)
func frames(runtime: any Runtime) throws -> [Frame] {
try Configs.defaultFrames(runtime: runtime, config: self)
}

@inlinable
func runtimeCalls(runtime: any Runtime) throws -> [any (StaticRuntimeCall & RuntimeValidatable).Type] {
func runtimeCalls(runtime: any Runtime) throws -> [any StaticRuntimeCall.Type] {
Configs.defaultRuntimeCalls(runtime: runtime, config: self)
}
}
Expand Down
Loading

0 comments on commit be4f43d

Please sign in to comment.