diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index 3ed7ee69c..50fa373c1 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -73,6 +73,7 @@ E921597D2065031D0000CA5C /* ButtonsStripe.xib in Resources */ = {isa = PBXBuildFile; fileRef = E921597C2065031D0000CA5C /* ButtonsStripe.xib */; }; E9220E0321983156009C9642 /* adamant-core.js in Resources */ = {isa = PBXBuildFile; fileRef = E9220E0121983155009C9642 /* adamant-core.js */; }; E9220E0421983156009C9642 /* JSAdamantCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9220E0221983155009C9642 /* JSAdamantCore.swift */; }; + E9220E08219879B9009C9642 /* NativeCoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9220E07219879B9009C9642 /* NativeCoreTests.swift */; }; E9256F5F2034C21100DE86E9 /* String+localized.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9256F5E2034C21100DE86E9 /* String+localized.swift */; }; E9256F6D20357B1700DE86E9 /* LogoFullHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9256F6C20357B1700DE86E9 /* LogoFullHeader.xib */; }; E9256F762039A9A200DE86E9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E9256F752039A9A200DE86E9 /* LaunchScreen.storyboard */; }; @@ -300,6 +301,7 @@ E921597C2065031D0000CA5C /* ButtonsStripe.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ButtonsStripe.xib; sourceTree = ""; }; E9220E0121983155009C9642 /* adamant-core.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "adamant-core.js"; sourceTree = ""; }; E9220E0221983155009C9642 /* JSAdamantCore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSAdamantCore.swift; sourceTree = ""; }; + E9220E07219879B9009C9642 /* NativeCoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeCoreTests.swift; sourceTree = ""; }; E9256F5E2034C21100DE86E9 /* String+localized.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+localized.swift"; sourceTree = ""; }; E9256F6C20357B1700DE86E9 /* LogoFullHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LogoFullHeader.xib; sourceTree = ""; }; E9256F752039A9A200DE86E9 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; @@ -653,14 +655,15 @@ path = ServerResponses; sourceTree = ""; }; - E9220E0021983145009C9642 /* JSCore */ = { + E9220E0021983145009C9642 /* Core */ = { isa = PBXGroup; children = ( E9220E0221983155009C9642 /* JSAdamantCore.swift */, E9220E0121983155009C9642 /* adamant-core.js */, E95F85762007E8EC0070534A /* JSAdamantCoreTests.swift */, + E9220E07219879B9009C9642 /* NativeCoreTests.swift */, ); - path = JSCore; + path = Core; sourceTree = ""; }; E93EB09D20DA3F3A001F9601 /* NodesEditor */ = { @@ -864,7 +867,7 @@ E9EC344520066D4A00C0E546 /* AdamantTests */ = { isa = PBXGroup; children = ( - E9220E0021983145009C9642 /* JSCore */, + E9220E0021983145009C9642 /* Core */, E95F85B8200A4D9C0070534A /* Parsing */, E950652020404BF0008352E5 /* AdamantUriBuilding.swift */, E9EC344620066D4A00C0E546 /* AddressValidationTests.swift */, @@ -1303,6 +1306,7 @@ E95F85772007E8EC0070534A /* JSAdamantCoreTests.swift in Sources */, E95F85712007D98D0070534A /* CurrencyFormatterTests.swift in Sources */, E950652120404BF0008352E5 /* AdamantUriBuilding.swift in Sources */, + E9220E08219879B9009C9642 /* NativeCoreTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Adamant.xcodeproj/xcshareddata/xcbaselines/E9EC344320066D4A00C0E546.xcbaseline/2F5A2BDA-A1C8-4C51-B0EB-6802181570B4.plist b/Adamant.xcodeproj/xcshareddata/xcbaselines/E9EC344320066D4A00C0E546.xcbaseline/2F5A2BDA-A1C8-4C51-B0EB-6802181570B4.plist index 80c9b65b8..f828ec7b7 100644 --- a/Adamant.xcodeproj/xcshareddata/xcbaselines/E9EC344320066D4A00C0E546.xcbaseline/2F5A2BDA-A1C8-4C51-B0EB-6802181570B4.plist +++ b/Adamant.xcodeproj/xcshareddata/xcbaselines/E9EC344320066D4A00C0E546.xcbaseline/2F5A2BDA-A1C8-4C51-B0EB-6802181570B4.plist @@ -37,6 +37,39 @@ + NativeCoreTests + + testPerformanceHashForPassphrase() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 1.179 + baselineIntegrationDisplayName + Local Baseline + + + testPerformanceKeypairForPassphrase() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 1.1729 + baselineIntegrationDisplayName + Local Baseline + + + testPerformanceSignTransaction() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.0018654 + baselineIntegrationDisplayName + Local Baseline + + + diff --git a/AdamantTests/JSCore/JSAdamantCore.swift b/AdamantTests/Core/JSAdamantCore.swift similarity index 97% rename from AdamantTests/JSCore/JSAdamantCore.swift rename to AdamantTests/Core/JSAdamantCore.swift index 5e903dbb6..e8895c390 100644 --- a/AdamantTests/JSCore/JSAdamantCore.swift +++ b/AdamantTests/Core/JSAdamantCore.swift @@ -37,6 +37,14 @@ enum AdamantCoreError: Error { /// You must load JavaScript before calling any methods. class JSAdamantCore : AdamantCore { + func encodeValue(_ value: [String : Any], privateKey: String) -> (message: String, nonce: String)? { + return nil + } + + func decodeValue(rawMessage: String, rawNonce: String, privateKey: String) -> String? { + return nil + } + enum Result { case success case error(error: Error) diff --git a/AdamantTests/JSCore/JSAdamantCoreTests.swift b/AdamantTests/Core/JSAdamantCoreTests.swift similarity index 93% rename from AdamantTests/JSCore/JSAdamantCoreTests.swift rename to AdamantTests/Core/JSAdamantCoreTests.swift index 89da08592..7ccb7eae4 100644 --- a/AdamantTests/JSCore/JSAdamantCoreTests.swift +++ b/AdamantTests/Core/JSAdamantCoreTests.swift @@ -15,7 +15,7 @@ class JSAdamantCoreTests: XCTestCase { override func setUp() { super.setUp() - guard let jsCore = Bundle.main.url(forResource: "adamant-core", withExtension: "js") else { + guard let jsCore = Bundle(for: type(of: self)).url(forResource: "adamant-core", withExtension: "js") else { fatalError("Can't load system resources!") } @@ -56,17 +56,17 @@ class JSAdamantCoreTests: XCTestCase { func testSignTransaction() { let transaction = NormalizedTransaction(type: TransactionType.send, - amount: 50000000, + amount: 60000000, senderPublicKey: "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f", requesterPublicKey: nil, - timestamp: 11325525, - recipientId: "U48484848484848484848484", + timestamp: 13131802, + recipientId: "U7038846184609740192", asset: TransactionAsset()) let senderId = "U2279741505997340299" let keypair = Keypair(publicKey: "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f", privateKey: "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f") - let signature = "cf2718a77527016ae1a847c190b0986e75fdc57926afc5aaebfa16fb7cb2cb64690b79cab9230f3328695770cf36370cc5be2b323419873081aa351d32b5db05" + let signature = "cdde6db8cfa9ebbca67f4625b0fdded5a130f01b4300423c4446e7b8ed79f95447be8b4dfd5d67b849d47bd9d834ddff3942499d350673e129f15ba2c1005807" let freshSignature = core.sign(transaction: transaction, senderId: senderId, keypair: keypair) XCTAssertEqual(signature, freshSignature) diff --git a/AdamantTests/Core/NativeCoreTests.swift b/AdamantTests/Core/NativeCoreTests.swift new file mode 100644 index 000000000..b673f41d9 --- /dev/null +++ b/AdamantTests/Core/NativeCoreTests.swift @@ -0,0 +1,197 @@ +// +// NativeCoreTests.swift +// AdamantTests +// +// Created by Anokhov Pavel on 11/11/2018. +// Copyright © 2018 Adamant. All rights reserved. +// + +import XCTest +@testable import Adamant + +class NativeCoreTests: XCTestCase { + var core: AdamantCore! + + override func setUp() { + super.setUp() + + core = NativeAdamantCore() + } + + func testHashForPassphrase() { + let passphrase = "process gospel angry height between flat always clock suit refuse shove verb" + let hash = "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab" + + let freshHash = core.createHashFor(passphrase: passphrase) + XCTAssertEqual(hash, freshHash) + } + + func testKeypairForPassphrase() { + let passphrase = "process gospel angry height between flat always clock suit refuse shove verb" + let publicKey = "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + let privateKey = "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + + let freshKeypair = core.createKeypairFor(passphrase: passphrase) + XCTAssertEqual(publicKey, freshKeypair?.publicKey) + XCTAssertEqual(privateKey, freshKeypair?.privateKey) + } + + func testGeneratePassphrase() { + let passphrase = core.generateNewPassphrase() + + XCTAssert(passphrase.split(separator: " ").count == 12) + } + + func testSignTransaction() { + let transaction = NormalizedTransaction(type: TransactionType.send, + amount: 60000000, + senderPublicKey: "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f", + requesterPublicKey: nil, + timestamp: 13131802, + recipientId: "U7038846184609740192", + asset: TransactionAsset()) + let senderId = "U2279741505997340299" + let keypair = Keypair(publicKey: "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f", + privateKey: "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f") + + let signature = "cdde6db8cfa9ebbca67f4625b0fdded5a130f01b4300423c4446e7b8ed79f95447be8b4dfd5d67b849d47bd9d834ddff3942499d350673e129f15ba2c1005807" + + let freshSignature = core.sign(transaction: transaction, senderId: senderId, keypair: keypair) + XCTAssertEqual(signature, freshSignature) + } + + func testEncodeMessage() { + let message = "common" + let aPublicKey = "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + let aPrivateKey = "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + let bPublicKey = "9f895a201fd92cc60ef02d2117d53f00dc2981903cb64b2f214777269b882209" + let bPrivateKey = "e91ee8e6a23ac5ff9452a15a3fbd14098dc2c6a5abf6b12464b09eb033580b6d9f895a201fd92cc60ef02d2117d53f00dc2981903cb64b2f214777269b882209" + + guard let encoded = core.encodeMessage(message, recipientPublicKey: bPublicKey, privateKey: aPrivateKey) else { + XCTFail() + return + } + + guard let decoded = core.decodeMessage(rawMessage: encoded.message, rawNonce: encoded.nonce, senderPublicKey: aPublicKey, privateKey: bPrivateKey) else { + XCTFail() + return + } + + XCTAssertEqual(message, decoded) + } + + func testDecodeMessage() { + let publicKey = "9f895a201fd92cc60ef02d2117d53f00dc2981903cb64b2f214777269b882209" + let privateKey = "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + let message = "09af1ce7e5ed484ddca3c6d1410cbf4f793ea19210e7" + let nonce = "31caaee2d35dcbd8b614e9d6bf6095393cb5baed259e7e37" + let decodedMessage = "common" + + let freshMessage = core.decodeMessage(rawMessage: message, rawNonce: nonce, senderPublicKey: publicKey, privateKey: privateKey) + + XCTAssertEqual(freshMessage, decodedMessage) + } + + // MARK: - JS to Native + + func testDecodeJsEncodedMessage() { + let message = "common" + let aPublicKey = "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + let aPrivateKey = "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + let bPublicKey = "9f895a201fd92cc60ef02d2117d53f00dc2981903cb64b2f214777269b882209" + let bPrivateKey = "e91ee8e6a23ac5ff9452a15a3fbd14098dc2c6a5abf6b12464b09eb033580b6d9f895a201fd92cc60ef02d2117d53f00dc2981903cb64b2f214777269b882209" + + guard let js = Bundle(for: type(of: self)).url(forResource: "adamant-core", withExtension: "js") else { + fatalError("Can't load system resources!") + } + + let jsCore = JSAdamantCore() + jsCore.loadJs(from: js, queue: DispatchQueue.global(qos: .utility)) { (result) in + if case .error = result { + fatalError() + } + } + + // Encode with JS + guard let encoded = jsCore.encodeMessage(message, recipientPublicKey: bPublicKey, privateKey: aPrivateKey) else { + XCTFail() + return + } + + // Decode with Native + guard let decoded = core.decodeMessage(rawMessage: encoded.message, rawNonce: encoded.nonce, senderPublicKey: aPublicKey, privateKey: bPrivateKey) else { + XCTFail() + return + } + + XCTAssertEqual(message, decoded) + } + + func testEncodeMessageForJs() { + let message = "common" + let aPublicKey = "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + let aPrivateKey = "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f" + let bPublicKey = "9f895a201fd92cc60ef02d2117d53f00dc2981903cb64b2f214777269b882209" + let bPrivateKey = "e91ee8e6a23ac5ff9452a15a3fbd14098dc2c6a5abf6b12464b09eb033580b6d9f895a201fd92cc60ef02d2117d53f00dc2981903cb64b2f214777269b882209" + + guard let js = Bundle(for: type(of: self)).url(forResource: "adamant-core", withExtension: "js") else { + fatalError("Can't load system resources!") + } + + let jsCore = JSAdamantCore() + jsCore.loadJs(from: js, queue: DispatchQueue.global(qos: .utility)) { (result) in + if case .error = result { + fatalError() + } + } + + // Encode with native + guard let encoded = core.encodeMessage(message, recipientPublicKey: bPublicKey, privateKey: aPrivateKey) else { + XCTFail() + return + } + + // Decode with JS + guard let decoded = jsCore.decodeMessage(rawMessage: encoded.message, rawNonce: encoded.nonce, senderPublicKey: aPublicKey, privateKey: bPrivateKey) else { + XCTFail() + return + } + + XCTAssertEqual(message, decoded) + } + + // MARK: - Performance + + func testPerformanceHashForPassphrase() { + let passphrase = "process gospel angry height between flat always clock suit refuse shove verb" + + self.measure { + _ = core.createHashFor(passphrase: passphrase) + } + } + + func testPerformanceKeypairForPassphrase() { + let passphrase = "process gospel angry height between flat always clock suit refuse shove verb" + + self.measure { + _ = core.createKeypairFor(passphrase: passphrase) + } + } + + func testPerformanceSignTransaction() { + let transaction = NormalizedTransaction(type: TransactionType.send, + amount: 50000000, + senderPublicKey: "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f", + requesterPublicKey: nil, + timestamp: 11325525, + recipientId: "U48484848484848484848484", + asset: TransactionAsset()) + let senderId = "U2279741505997340299" + let keypair = Keypair(publicKey: "8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f", + privateKey: "9001490b166816af75a15a3e2b0174bfe3be3dfaa63147b4f780ed3ab90ffeab8007a01493bb4b21ec67265769898eb19514d9427bd7b701f96bc9880a6e209f") + + self.measure { + _ = core.sign(transaction: transaction, senderId: senderId, keypair: keypair) + } + } +} diff --git a/AdamantTests/JSCore/adamant-core.js b/AdamantTests/Core/adamant-core.js similarity index 100% rename from AdamantTests/JSCore/adamant-core.js rename to AdamantTests/Core/adamant-core.js