Skip to content

Commit

Permalink
Merge pull request #29 from nova-wallet/fix/decode-signed-int
Browse files Browse the repository at this point in the history
Fix signed int decoding and encoding
  • Loading branch information
ERussel authored Oct 6, 2022
2 parents 1be5012 + 9063bd5 commit 2fadfd8
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 11 deletions.
4 changes: 4 additions & 0 deletions Example/SubstrateSdk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
84AF377F271DE550007408D6 /* ScaleInfoMappingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AF377E271DE550007408D6 /* ScaleInfoMappingTests.swift */; };
84AF378527215DB4007408D6 /* ValidatorPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AF378427215DB4007408D6 /* ValidatorPrefs.swift */; };
84AF378727221F02007408D6 /* common-v14.json in Resources */ = {isa = PBXBuildFile; fileRef = 84AF378627221F01007408D6 /* common-v14.json */; };
84C41F3A28EE157600DB1CD3 /* SignedIntNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C41F3928EE157600DB1CD3 /* SignedIntNodeTests.swift */; };
84CB472424DBE82C00837E11 /* KeystoreExtractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CB472324DBE82C00837E11 /* KeystoreExtractorTests.swift */; };
84CB472524DBE98500837E11 /* keystore-sr25519.json in Resources */ = {isa = PBXBuildFile; fileRef = 84CB472024DBE7E100837E11 /* keystore-sr25519.json */; };
84DA3B3C24C8CE5900B5E27F /* ScaleUInt32Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DA3B3224C8CE5900B5E27F /* ScaleUInt32Tests.swift */; };
Expand Down Expand Up @@ -216,6 +217,7 @@
84AF377E271DE550007408D6 /* ScaleInfoMappingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaleInfoMappingTests.swift; sourceTree = "<group>"; };
84AF378427215DB4007408D6 /* ValidatorPrefs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidatorPrefs.swift; sourceTree = "<group>"; };
84AF378627221F01007408D6 /* common-v14.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "common-v14.json"; sourceTree = "<group>"; };
84C41F3928EE157600DB1CD3 /* SignedIntNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignedIntNodeTests.swift; sourceTree = "<group>"; };
84CB472024DBE7E100837E11 /* keystore-sr25519.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "keystore-sr25519.json"; sourceTree = "<group>"; };
84CB472324DBE82C00837E11 /* KeystoreExtractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeystoreExtractorTests.swift; sourceTree = "<group>"; };
84DA3B3224C8CE5900B5E27F /* ScaleUInt32Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScaleUInt32Tests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -431,6 +433,7 @@
84452C7C25D3F75800F47EC5 /* GenericCallNodeTests.swift */,
84452C8225D3F97F00F47EC5 /* GenericEventNodeTests.swift */,
84452D9225D48FC100F47EC5 /* ExtrinsicNodeTests.swift */,
84C41F3928EE157600DB1CD3 /* SignedIntNodeTests.swift */,
);
path = Generic;
sourceTree = "<group>";
Expand Down Expand Up @@ -890,6 +893,7 @@
84DA3B4024C8CE5900B5E27F /* ScaleInt8Tests.swift in Sources */,
84AF377F271DE550007408D6 /* ScaleInfoMappingTests.swift in Sources */,
84DA3B4524C8CE5A00B5E27F /* ScaleUInt8Tests.swift in Sources */,
84C41F3A28EE157600DB1CD3 /* SignedIntNodeTests.swift in Sources */,
84F43A6125DC701F00AEDA56 /* Reasons.swift in Sources */,
84AF377A271DA9A2007408D6 /* ScaleRegistryTests.swift in Sources */,
84F43B4625DE800F00AEDA56 /* ExtrinsicBuilderTests.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion SubstrateSdk.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Pod::Spec.new do |s|
s.name = 'SubstrateSdk'
s.version = '1.4.0'
s.version = '1.4.1'
s.summary = 'Utility library that implements clients specific logic to interact with substrate based networks'

s.homepage = 'https://github.com/nova-wallet/substrate-sdk-ios'
Expand Down
4 changes: 2 additions & 2 deletions SubstrateSdk/Classes/Runtime/Nodes/Items/BasicNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ public class I32Node: Node {
public init() {}

public func accept(encoder: DynamicScaleEncoding, value: JSON) throws {
try encoder.appendU32(json: value)
try encoder.appendI32(json: value)
}

public func accept(decoder: DynamicScaleDecoding) throws -> JSON {
try decoder.readU32()
try decoder.readI32()
}
}

Expand Down
14 changes: 7 additions & 7 deletions SubstrateSdk/Classes/Scale/DynamicScaleDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public class DynamicScaleDecoder {
private func decodeSignedInt(length: Int) throws -> JSON {
let data = try decoder.readAndConfirm(count: length)
let magnitude = BigUInt(Data(data.reversed()))
let signMask = BigUInt(1) << (length - 1)
let signMask = BigUInt(1) << (8 * length - 1)
let sign: BigInt.Sign = (magnitude & signMask) == 0 ? .plus : .minus

let value: BigInt
Expand Down Expand Up @@ -175,27 +175,27 @@ extension DynamicScaleDecoder: DynamicScaleDecoding {
}

public func readI8() throws -> JSON {
try decodeFixedInt(length: 1)
try decodeSignedInt(length: 1)
}

public func readI16() throws -> JSON {
try decodeFixedInt(length: 2)
try decodeSignedInt(length: 2)
}

public func readI32() throws -> JSON {
try decodeFixedInt(length: 4)
try decodeSignedInt(length: 4)
}

public func readI64() throws -> JSON {
try decodeFixedInt(length: 8)
try decodeSignedInt(length: 8)
}

public func readI128() throws -> JSON {
try decodeFixedInt(length: 16)
try decodeSignedInt(length: 16)
}

public func readI256() throws -> JSON {
try decodeFixedInt(length: 32)
try decodeSignedInt(length: 32)
}

public func readBool() throws -> JSON {
Expand Down
3 changes: 2 additions & 1 deletion SubstrateSdk/Classes/Scale/DynamicScaleEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public final class DynamicScaleEncoder {
case .plus:
magnitude = intValue.magnitude
case .minus:
let invertingMask = (BigUInt(1) << byteLength) - 1
let bitLength = 8 * byteLength
let invertingMask = (BigUInt(1) << bitLength) - 1
magnitude = (intValue.magnitude ^ invertingMask) + 1
}

Expand Down
57 changes: 57 additions & 0 deletions Tests/Runtime/Generic/SignedIntNodeTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import XCTest
import SubstrateSdk
import BigInt

class SignedIntNodeTests: XCTestCase {
let typeRegistry = try! RuntimeHelper.createTypeRegistryCatalog(
from: "default",
networkName: "westend",
runtimeMetadataName: "westend-metadata"
)

func testSignedIntEncodingDecoding() {
let bitLengths = [8, 16, 32, 64, 128, 256]

bitLengths.forEach { bitLength in
let type = "I\(bitLength)"
performEncodingDecodingTest(for: .stringValue("0"), type: type)
performEncodingDecodingTest(for: .stringValue("1"), type: type)
performEncodingDecodingTest(for: .stringValue("-1"), type: type)
performEncodingDecodingTest(for: .stringValue("127"), type: type)
performEncodingDecodingTest(for: .stringValue("-127"), type: type)
performEncodingDecodingTest(for: .stringValue("53"), type: type)
performEncodingDecodingTest(for: .stringValue("-53"), type: type)

let typeValue = BigUInt(1) << (bitLength - 2)
let positiveValue = String(typeValue)
let negativeValue = "-" + String(typeValue)

performEncodingDecodingTest(for: .stringValue(positiveValue), type: type)
performEncodingDecodingTest(for: .stringValue(negativeValue), type: type)
}
}

// MARK: Private

private func performEncodingDecodingTest(for value: JSON, type: String) {
do {
let encodedValue = try performEncoding(value: value, type: type)
try performDecodingTest(data: encodedValue, type: type, expected: value)
} catch {
XCTFail("Unexpected error: \(error)")
}
}

private func performDecodingTest(data: Data, type: String, expected: JSON) throws {
let decoder = try DynamicScaleDecoder(data: data, registry: typeRegistry, version: 45)
let result = try decoder.read(type: type)
XCTAssertEqual(expected, result)
XCTAssertEqual(decoder.remained, 0)
}

private func performEncoding(value: JSON, type: String) throws -> Data {
let encoder = DynamicScaleEncoder(registry: typeRegistry, version: 45)
try encoder.append(json: value, type: type)
return try encoder.encode()
}
}

0 comments on commit 2fadfd8

Please sign in to comment.