From 471b8721d9ab03c628ac3fb0e3adf10cd83a3d60 Mon Sep 17 00:00:00 2001 From: Shun Usami Date: Fri, 13 Sep 2019 13:56:37 +0900 Subject: [PATCH] :recycle: Update to Swift5 iOS/Linux - Data(bytes:) to Data() - index(of:) to firstIndex(of:) - Refactor deprecated withUnsafeBytes() methods. UnsafePointer -> UnsafeRawBufferPointer Linux - RunLoopMode to RunLoop.Mode - Update Package.swift swift-tools-version to 5.0 --- BitcoinKit.xcodeproj/project.pbxproj | 8 +-- Package.swift | 4 +- .../Core/BitcoinKitPrivateSwift.swift | 12 ++--- Sources/BitcoinKit/Core/BlockStore.swift | 32 +++++------ Sources/BitcoinKit/Core/Helpers.swift | 2 +- Sources/BitcoinKit/Core/Keys/Encoding.swift | 11 ++-- Sources/BitcoinKit/Core/Keys/PrivateKey.swift | 2 +- Sources/BitcoinKit/Core/Mnemonic.swift | 2 +- Sources/BitcoinKit/Core/Serialization.swift | 9 ++-- Sources/BitcoinKit/Networking/Peer.swift | 14 ++--- .../Scripts/ScriptChunkHelper.swift | 53 +++++++++++-------- .../Scripts/ScriptExecutionContext.swift | 2 +- 12 files changed, 75 insertions(+), 76 deletions(-) diff --git a/BitcoinKit.xcodeproj/project.pbxproj b/BitcoinKit.xcodeproj/project.pbxproj index 2da19da3..920349b0 100644 --- a/BitcoinKit.xcodeproj/project.pbxproj +++ b/BitcoinKit.xcodeproj/project.pbxproj @@ -209,6 +209,7 @@ 6E20AED72112D417008A9810 /* MurmurHashTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E20AED62112D417008A9810 /* MurmurHashTests.swift */; }; 6E797C452116C8A5003BEDFD /* OpCodeFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E797C442116C8A5003BEDFD /* OpCodeFactoryTests.swift */; }; 6EE789DB2112C1E500EAB620 /* CryptoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EE789DA2112C1E500EAB620 /* CryptoTests.swift */; }; + A201ABB6222ACF7100DEFE13 /* BitcoinKitPrivateSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = A201ABB5222ACF7100DEFE13 /* BitcoinKitPrivateSwift.swift */; }; A20B537F211C72F9009D147A /* UInt256Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A20B537E211C72F9009D147A /* UInt256Tests.swift */; }; A246ED102118621B0000418D /* MerkleTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = A246ED0F2118621B0000418D /* MerkleTree.swift */; }; A246ED12211864500000418D /* UInt256.swift in Sources */ = {isa = PBXBuildFile; fileRef = A246ED11211864500000418D /* UInt256.swift */; }; @@ -220,7 +221,6 @@ A2DE5110212AFCF200F54EA0 /* UInt256+BitcoinTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2DE510F212AFCF200F54EA0 /* UInt256+BitcoinTests.swift */; }; A2E11231212C400A00A0A40A /* ProofOfWorkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2E11230212C400A00A0A40A /* ProofOfWorkTests.swift */; }; A2F06FBA2126785200DFF652 /* UInt32+Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F06FB92126785200DFF652 /* UInt32+Utility.swift */; }; - A201ABB6222ACF7100DEFE13 /* BitcoinKitPrivateSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = A201ABB5222ACF7100DEFE13 /* BitcoinKitPrivateSwift.swift */; }; CF432AF220F0CF9100AD4020 /* Base58Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF432AF120F0CF9100AD4020 /* Base58Tests.swift */; }; CF432AF420F0DFAC00AD4020 /* Bech32Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF432AF320F0DFAC00AD4020 /* Bech32Tests.swift */; }; CF432AF620F0ED4500AD4020 /* AddressTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF432AF520F0ED4500AD4020 /* AddressTests.swift */; }; @@ -455,6 +455,7 @@ 6E20AED62112D417008A9810 /* MurmurHashTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MurmurHashTests.swift; sourceTree = ""; }; 6E797C442116C8A5003BEDFD /* OpCodeFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpCodeFactoryTests.swift; sourceTree = ""; }; 6EE789DA2112C1E500EAB620 /* CryptoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoTests.swift; sourceTree = ""; }; + A201ABB5222ACF7100DEFE13 /* BitcoinKitPrivateSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BitcoinKitPrivateSwift.swift; path = Core/BitcoinKitPrivateSwift.swift; sourceTree = ""; }; A20B537E211C72F9009D147A /* UInt256Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UInt256Tests.swift; sourceTree = ""; }; A246ED0F2118621B0000418D /* MerkleTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerkleTree.swift; sourceTree = ""; }; A246ED11211864500000418D /* UInt256.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UInt256.swift; sourceTree = ""; }; @@ -466,7 +467,6 @@ A2DE510F212AFCF200F54EA0 /* UInt256+BitcoinTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt256+BitcoinTests.swift"; sourceTree = ""; }; A2E11230212C400A00A0A40A /* ProofOfWorkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProofOfWorkTests.swift; sourceTree = ""; }; A2F06FB92126785200DFF652 /* UInt32+Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt32+Utility.swift"; sourceTree = ""; }; - A201ABB5222ACF7100DEFE13 /* BitcoinKitPrivateSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BitcoinKitPrivateSwift.swift; path = Core/BitcoinKitPrivateSwift.swift; sourceTree = ""; }; CF432AF120F0CF9100AD4020 /* Base58Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base58Tests.swift; sourceTree = ""; }; CF432AF320F0DFAC00AD4020 /* Bech32Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bech32Tests.swift; sourceTree = ""; }; CF432AF520F0ED4500AD4020 /* AddressTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressTests.swift; sourceTree = ""; }; @@ -1488,7 +1488,7 @@ SKIP_INSTALL = YES; SWIFT_INCLUDE_PATHS = "$(SRCROOT)/Libraries"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -1526,7 +1526,7 @@ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; SWIFT_INCLUDE_PATHS = "$(SRCROOT)/Libraries"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Package.swift b/Package.swift index ceb56725..1298652c 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:4.0 +// swift-tools-version:5.0 import PackageDescription let package = Package( @@ -25,5 +25,5 @@ let package = Package( dependencies: ["BitcoinKit"] ) ], - swiftLanguageVersions: [4] + swiftLanguageVersions: [.v5] ) diff --git a/Sources/BitcoinKit/Core/BitcoinKitPrivateSwift.swift b/Sources/BitcoinKit/Core/BitcoinKitPrivateSwift.swift index c171602e..615e8719 100644 --- a/Sources/BitcoinKit/Core/BitcoinKitPrivateSwift.swift +++ b/Sources/BitcoinKit/Core/BitcoinKitPrivateSwift.swift @@ -50,7 +50,7 @@ class _SwiftKey { if outputlen != 33 { return Data() } - return Data(bytes: serializedPubkey) + return Data(serializedPubkey) } else { var serializedPubkey = [UInt8](repeating: 0, count: 65) var outputlen = 65 @@ -60,7 +60,7 @@ class _SwiftKey { if outputlen != 65 { return Data() } - return Data(bytes: serializedPubkey) + return Data(serializedPubkey) } } } @@ -110,7 +110,7 @@ class _HDKey { if secp256k1_ec_privkey_tweak_add(ctx, &privateKeyBytes, &derivedPrivateKeyBytes) == 0 { return nil } - result = Data(bytes: privateKeyBytes) + result = Data(privateKeyBytes) } else { guard let ctx = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_VERIFY)) else { return nil @@ -129,10 +129,10 @@ class _HDKey { if secp256k1_ec_pubkey_serialize(ctx, &compressedPublicKeyBytes, &compressedPublicKeyBytesLen, &secpPubkey, UInt32(SECP256K1_EC_COMPRESSED)) == 0 { return nil } - result = Data(bytes: compressedPublicKeyBytes) + result = Data(compressedPublicKeyBytes) } - let fingerPrint: UInt32 = _Hash.sha256ripemd160(publicKey).withUnsafeBytes { $0.pointee } - return _HDKey(privateKey: result, publicKey: result, chainCode: Data(bytes: derivedChainCode), depth: self.depth + 1, fingerprint: fingerPrint, childIndex: childIndex) + let fingerPrint: UInt32 = _Hash.sha256ripemd160(publicKey).to(type: UInt32.self) + return _HDKey(privateKey: result, publicKey: result, chainCode: Data(derivedChainCode), depth: self.depth + 1, fingerprint: fingerPrint, childIndex: childIndex) } } #endif diff --git a/Sources/BitcoinKit/Core/BlockStore.swift b/Sources/BitcoinKit/Core/BlockStore.swift index ccf94803..93228938 100644 --- a/Sources/BitcoinKit/Core/BlockStore.swift +++ b/Sources/BitcoinKit/Core/BlockStore.swift @@ -291,10 +291,10 @@ public class SQLiteBlockStore: BlockStore { public func addBlock(_ block: BlockMessage, hash: Data) throws { let stmt = statements["addBlock"] - try execute { hash.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0, Int32(hash.count), SQLITE_TRANSIENT) } } + try execute { hash.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0.baseAddress.unsafelyUnwrapped, Int32(hash.count), SQLITE_TRANSIENT) } } try execute { sqlite3_bind_int64(stmt, 2, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: block.version))) } - try execute { block.prevBlock.withUnsafeBytes { sqlite3_bind_blob(stmt, 3, $0, Int32(block.prevBlock.count), SQLITE_TRANSIENT) } } - try execute { block.merkleRoot.withUnsafeBytes { sqlite3_bind_blob(stmt, 4, $0, Int32(block.merkleRoot.count), SQLITE_TRANSIENT) } } + try execute { block.prevBlock.withUnsafeBytes { sqlite3_bind_blob(stmt, 3, $0.baseAddress.unsafelyUnwrapped, Int32(block.prevBlock.count), SQLITE_TRANSIENT) } } + try execute { block.merkleRoot.withUnsafeBytes { sqlite3_bind_blob(stmt, 4, $0.baseAddress.unsafelyUnwrapped, Int32(block.merkleRoot.count), SQLITE_TRANSIENT) } } try execute { sqlite3_bind_int64(stmt, 5, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: block.timestamp))) } try execute { sqlite3_bind_int64(stmt, 6, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: block.bits))) } try execute { sqlite3_bind_int64(stmt, 7, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: block.nonce))) } @@ -307,20 +307,20 @@ public class SQLiteBlockStore: BlockStore { public func addMerkleBlock(_ merkleBlock: MerkleBlockMessage, hash: Data) throws { let stmt = statements["addMerkleBlock"] - try execute { hash.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0, Int32(hash.count), SQLITE_TRANSIENT) } } + try execute { hash.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0.baseAddress.unsafelyUnwrapped, Int32(hash.count), SQLITE_TRANSIENT) } } try execute { sqlite3_bind_int64(stmt, 2, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: merkleBlock.version))) } - try execute { merkleBlock.prevBlock.withUnsafeBytes { sqlite3_bind_blob(stmt, 3, $0, Int32(merkleBlock.prevBlock.count), SQLITE_TRANSIENT) } } - try execute { merkleBlock.merkleRoot.withUnsafeBytes { sqlite3_bind_blob(stmt, 4, $0, Int32(merkleBlock.merkleRoot.count), SQLITE_TRANSIENT) } } + try execute { merkleBlock.prevBlock.withUnsafeBytes { sqlite3_bind_blob(stmt, 3, $0.baseAddress.unsafelyUnwrapped, Int32(merkleBlock.prevBlock.count), SQLITE_TRANSIENT) } } + try execute { merkleBlock.merkleRoot.withUnsafeBytes { sqlite3_bind_blob(stmt, 4, $0.baseAddress.unsafelyUnwrapped, Int32(merkleBlock.merkleRoot.count), SQLITE_TRANSIENT) } } try execute { sqlite3_bind_int64(stmt, 5, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: merkleBlock.timestamp))) } try execute { sqlite3_bind_int64(stmt, 6, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: merkleBlock.bits))) } try execute { sqlite3_bind_int64(stmt, 7, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: merkleBlock.nonce))) } try execute { sqlite3_bind_int64(stmt, 8, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: merkleBlock.totalTransactions))) } try execute { sqlite3_bind_int64(stmt, 9, sqlite3_int64(bitPattern: merkleBlock.numberOfHashes.underlyingValue)) } let hashes = Data(merkleBlock.hashes.flatMap { $0 }) - try execute { hashes.withUnsafeBytes { sqlite3_bind_blob(stmt, 10, $0, Int32(hashes.count), SQLITE_TRANSIENT) } } + try execute { hashes.withUnsafeBytes { sqlite3_bind_blob(stmt, 10, $0.baseAddress.unsafelyUnwrapped, Int32(hashes.count), SQLITE_TRANSIENT) } } try execute { sqlite3_bind_int64(stmt, 11, sqlite3_int64(bitPattern: merkleBlock.numberOfFlags.underlyingValue)) } let flags = Data(merkleBlock.flags) - try execute { flags.withUnsafeBytes { sqlite3_bind_blob(stmt, 12, $0, Int32(flags.count), SQLITE_TRANSIENT) } } + try execute { flags.withUnsafeBytes { sqlite3_bind_blob(stmt, 12, $0.baseAddress.unsafelyUnwrapped, Int32(flags.count), SQLITE_TRANSIENT) } } try executeUpdate { sqlite3_step(stmt) } try execute { sqlite3_reset(stmt) } @@ -329,7 +329,7 @@ public class SQLiteBlockStore: BlockStore { public func addTransaction(_ transaction: Transaction, hash: Data) throws { let stmt = statements["addTransaction"] - try execute { hash.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0, Int32(hash.count), SQLITE_TRANSIENT) } } + try execute { hash.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0.baseAddress.unsafelyUnwrapped, Int32(hash.count), SQLITE_TRANSIENT) } } try execute { sqlite3_bind_int64(stmt, 2, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: transaction.version))) } try execute { sqlite3_bind_int(stmt, 3, 0) } // Not supported 'flag' currently try execute { sqlite3_bind_int64(stmt, 4, sqlite3_int64(bitPattern: transaction.txInCount.underlyingValue)) } @@ -353,10 +353,10 @@ public class SQLiteBlockStore: BlockStore { let stmt = statements["addTransactionInput"] try execute { sqlite3_bind_int64(stmt, 1, sqlite3_int64(bitPattern: input.scriptLength.underlyingValue)) } - try execute { input.signatureScript.withUnsafeBytes { sqlite3_bind_blob(stmt, 2, $0, Int32(input.signatureScript.count), SQLITE_TRANSIENT) } } + try execute { input.signatureScript.withUnsafeBytes { sqlite3_bind_blob(stmt, 2, $0.baseAddress.unsafelyUnwrapped, Int32(input.signatureScript.count), SQLITE_TRANSIENT) } } try execute { sqlite3_bind_int64(stmt, 3, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: input.sequence))) } - try execute { txId.withUnsafeBytes { sqlite3_bind_blob(stmt, 4, $0, Int32(txId.count), SQLITE_TRANSIENT) } } - try execute { input.previousOutput.hash.withUnsafeBytes { sqlite3_bind_blob(stmt, 5, $0, Int32(input.previousOutput.hash.count), SQLITE_TRANSIENT) } } + try execute { txId.withUnsafeBytes { sqlite3_bind_blob(stmt, 4, $0.baseAddress.unsafelyUnwrapped, Int32(txId.count), SQLITE_TRANSIENT) } } + try execute { input.previousOutput.hash.withUnsafeBytes { sqlite3_bind_blob(stmt, 5, $0.baseAddress.unsafelyUnwrapped, Int32(input.previousOutput.hash.count), SQLITE_TRANSIENT) } } try executeUpdate { sqlite3_step(stmt) } try execute { sqlite3_reset(stmt) } @@ -368,8 +368,8 @@ public class SQLiteBlockStore: BlockStore { try execute { sqlite3_bind_int64(stmt, 1, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: index))) } try execute { sqlite3_bind_int64(stmt, 2, sqlite3_int64(bitPattern: UInt64(truncatingIfNeeded: output.value))) } try execute { sqlite3_bind_int64(stmt, 3, sqlite3_int64(bitPattern: output.scriptLength.underlyingValue)) } - try execute { output.lockingScript.withUnsafeBytes { sqlite3_bind_blob(stmt, 4, $0, Int32(output.lockingScript.count), SQLITE_TRANSIENT) } } - try execute { txId.withUnsafeBytes { sqlite3_bind_blob(stmt, 5, $0, Int32(txId.count), SQLITE_TRANSIENT) } } + try execute { output.lockingScript.withUnsafeBytes { sqlite3_bind_blob(stmt, 4, $0.baseAddress.unsafelyUnwrapped, Int32(output.lockingScript.count), SQLITE_TRANSIENT) } } + try execute { txId.withUnsafeBytes { sqlite3_bind_blob(stmt, 5, $0.baseAddress.unsafelyUnwrapped, Int32(txId.count), SQLITE_TRANSIENT) } } if Script.isPublicKeyHashOut(output.lockingScript) { let pubKeyHash = Script.getPublicKeyHash(from: output.lockingScript) let address = publicKeyHashToAddress(Data([network.pubkeyhash]) + pubKeyHash) @@ -382,14 +382,14 @@ public class SQLiteBlockStore: BlockStore { private func deleteTransactionInput(txId: Data) throws { let stmt = statements["deleteTransactionInput"] - try execute { txId.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0, Int32(txId.count), SQLITE_TRANSIENT) } } + try execute { txId.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0.baseAddress.unsafelyUnwrapped, Int32(txId.count), SQLITE_TRANSIENT) } } try executeUpdate { sqlite3_step(stmt) } try execute { sqlite3_reset(stmt) } } private func deleteTransactionOutput(txId: Data) throws { let stmt = statements["deleteTransactionOutput"] - try execute { txId.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0, Int32(txId.count), SQLITE_TRANSIENT) } } + try execute { txId.withUnsafeBytes { sqlite3_bind_blob(stmt, 1, $0.baseAddress.unsafelyUnwrapped, Int32(txId.count), SQLITE_TRANSIENT) } } try executeUpdate { sqlite3_step(stmt) } try execute { sqlite3_reset(stmt) } } diff --git a/Sources/BitcoinKit/Core/Helpers.swift b/Sources/BitcoinKit/Core/Helpers.swift index 6035fd73..a1a98bd1 100644 --- a/Sources/BitcoinKit/Core/Helpers.swift +++ b/Sources/BitcoinKit/Core/Helpers.swift @@ -39,7 +39,7 @@ func pton(_ address: String) -> Data { inet_pton(AF_INET6, address, UnsafeMutablePointer($0)) } var buffer = Data(count: 16) - _ = buffer.withUnsafeMutableBytes { memcpy($0, &addr, 16) } + _ = buffer.withUnsafeMutableBytes { memcpy($0.baseAddress.unsafelyUnwrapped, &addr, 16) } return buffer } diff --git a/Sources/BitcoinKit/Core/Keys/Encoding.swift b/Sources/BitcoinKit/Core/Keys/Encoding.swift index f0be9ac7..69b7ec96 100644 --- a/Sources/BitcoinKit/Core/Keys/Encoding.swift +++ b/Sources/BitcoinKit/Core/Keys/Encoding.swift @@ -134,7 +134,7 @@ extension Encoding { let size = sizeFromBase(size: string.lengthOfBytes(using: .utf8) - zerosCount) var decodedBytes: [UInt8] = Array(repeating: 0, count: size) for c in string { - guard let baseIndex: Int = baseAlphabets.index(of: c)?.utf16Offset(in: baseAlphabets) else { return nil } + guard let baseIndex: Int = baseAlphabets.firstIndex(of: c)?.utf16Offset(in: baseAlphabets) else { return nil } var carry = baseIndex var i = 0 for j in (0...decodedBytes.count - 1).reversed() where carry != 0 || i < length { @@ -195,15 +195,14 @@ public struct Bech32 { var decodedIn5bit: [UInt8] = [UInt8]() for c in base32.lowercased() { // We can't have characters other than base32 alphabets. - print(base32Alphabets) - guard let baseIndex = base32Alphabets.index(of: c)?.utf16Offset(in: base32Alphabets) else { + guard let baseIndex = base32Alphabets.firstIndex(of: c)?.utf16Offset(in: base32Alphabets) else { return nil } decodedIn5bit.append(UInt8(baseIndex)) } // We can't have invalid checksum - let payload = Data(bytes: decodedIn5bit) + let payload = Data(decodedIn5bit) guard verifyChecksum(prefix: prefix, payload: payload) else { return nil } @@ -272,7 +271,7 @@ public struct Bech32 { if pad && bits > 0 { converted.append(lastBits) } - return Data(bytes: converted) + return Data(converted) } internal static func convertFrom5bit(data: Data) throws -> Data { @@ -298,7 +297,7 @@ public struct Bech32 { throw DecodeError.invalidBits } - return Data(bytes: converted) + return Data(converted) } private enum DecodeError: Error { diff --git a/Sources/BitcoinKit/Core/Keys/PrivateKey.swift b/Sources/BitcoinKit/Core/Keys/PrivateKey.swift index bd114697..c81c3309 100644 --- a/Sources/BitcoinKit/Core/Keys/PrivateKey.swift +++ b/Sources/BitcoinKit/Core/Keys/PrivateKey.swift @@ -72,7 +72,7 @@ public struct PrivateKey { var key = Data(count: count) var status: Int32 = 0 repeat { - status = key.withUnsafeMutableBytes { SecRandomCopyBytes(kSecRandomDefault, count, $0) } + status = key.withUnsafeMutableBytes { SecRandomCopyBytes(kSecRandomDefault, count, $0.baseAddress.unsafelyUnwrapped) } } while (status != 0 || !check([UInt8](key))) self.data = key diff --git a/Sources/BitcoinKit/Core/Mnemonic.swift b/Sources/BitcoinKit/Core/Mnemonic.swift index 14647341..b361c8c2 100644 --- a/Sources/BitcoinKit/Core/Mnemonic.swift +++ b/Sources/BitcoinKit/Core/Mnemonic.swift @@ -53,7 +53,7 @@ public struct Mnemonic { public static func generate(strength: Strength = .default, language: Language = .english) throws -> [String] { let byteCount = strength.rawValue / 8 var bytes = Data(count: byteCount) - let status = bytes.withUnsafeMutableBytes { SecRandomCopyBytes(kSecRandomDefault, byteCount, $0) } + let status = bytes.withUnsafeMutableBytes { SecRandomCopyBytes(kSecRandomDefault, byteCount, $0.baseAddress.unsafelyUnwrapped) } guard status == errSecSuccess else { throw MnemonicError.randomBytesError } return generate(entropy: bytes, language: language) } diff --git a/Sources/BitcoinKit/Core/Serialization.swift b/Sources/BitcoinKit/Core/Serialization.swift index a23c8970..1e74ced1 100644 --- a/Sources/BitcoinKit/Core/Serialization.swift +++ b/Sources/BitcoinKit/Core/Serialization.swift @@ -91,11 +91,10 @@ extension Data { } func to(type: T.Type) -> T { - var data = self - while data.count < MemoryLayout.size { - data.append(0) - } - return data.withUnsafeBytes { $0.pointee } + var data = Data(count: MemoryLayout.size) + // Doing this for aligning memory layout + _ = data.withUnsafeMutableBytes { self.copyBytes(to: $0) } + return data.withUnsafeBytes { $0.load(as: T.self) } } func to(type: String.Type) -> String { diff --git a/Sources/BitcoinKit/Networking/Peer.swift b/Sources/BitcoinKit/Networking/Peer.swift index ceae93b1..28b64f4b 100644 --- a/Sources/BitcoinKit/Networking/Peer.swift +++ b/Sources/BitcoinKit/Networking/Peer.swift @@ -90,13 +90,8 @@ public class Peer: NSObject, StreamDelegate { inputStream.delegate = self outputStream.delegate = self - #if BitcoinKitXcode inputStream.schedule(in: .current, forMode: .common) outputStream.schedule(in: .current, forMode: .common) - #else - inputStream.schedule(in: .current, forMode: RunLoopMode.commonModes) - outputStream.schedule(in: .current, forMode: RunLoopMode.commonModes) - #endif inputStream.open() outputStream.open() @@ -109,13 +104,8 @@ public class Peer: NSObject, StreamDelegate { inputStream.delegate = nil outputStream.delegate = nil - #if BitcoinKitXcode inputStream.remove(from: .current, forMode: .common) outputStream.remove(from: .current, forMode: .common) - #else - inputStream.remove(from: .current, forMode: RunLoopMode.commonModes) - outputStream.remove(from: .current, forMode: RunLoopMode.commonModes) - #endif inputStream.close() outputStream.close() @@ -255,7 +245,9 @@ public class Peer: NSObject, StreamDelegate { private func sendMessage(_ message: Message) { log("sending \(message.command)") let data = message.serialized() - _ = data.withUnsafeBytes { outputStream.write($0, maxLength: data.count) } + data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> Void in + outputStream.write(ptr.bindMemory(to: UInt8.self).baseAddress.unsafelyUnwrapped, maxLength: data.count) + } } private func sendVersionMessage() { diff --git a/Sources/BitcoinKit/Scripts/ScriptChunkHelper.swift b/Sources/BitcoinKit/Scripts/ScriptChunkHelper.swift index 6ef9bbc7..cfdf46ec 100644 --- a/Sources/BitcoinKit/Scripts/ScriptChunkHelper.swift +++ b/Sources/BitcoinKit/Scripts/ScriptChunkHelper.swift @@ -76,41 +76,50 @@ public struct ScriptChunkHelper { private static func parseDataChunk(from scriptData: Data, offset: Int, opcode: UInt8) throws -> DataChunk { // for range let count: Int = scriptData.count - let chunkLength: Int +// let chunkLength: Int + let opCodeSize: Int = MemoryLayout.size + let dataLengthSize: Int + let dataSize: Int + var chunkLength: Int { + return opCodeSize + dataLengthSize + dataSize + } switch opcode { case 0...size + guard offset + opCodeSize + dataLengthSize <= count else { throw ScriptChunkError.error("Parse DataChunk failed. OP_PUSHDATA1 error") } - _ = scriptData.withUnsafeBytes { - memcpy(&dataLength, $0 + offset + MemoryLayout.size(ofValue: opcode), MemoryLayout.size(ofValue: dataLength)) + dataSize = scriptData.withUnsafeBytes { + Int($0.load(fromByteOffset: offset + opCodeSize, as: UInt8.self)) } - chunkLength = MemoryLayout.size(ofValue: opcode) + MemoryLayout.size(ofValue: dataLength) + Int(dataLength) case OpCode.OP_PUSHDATA2.value: - var dataLength = UInt16() - guard offset + MemoryLayout.size(ofValue: dataLength) <= count else { - throw ScriptChunkError.error("Parse DataChunk failed. OP_PUSHDATA2 error") + dataLengthSize = MemoryLayout.size + guard offset + opCodeSize + dataLengthSize <= count else { + throw ScriptChunkError.error("Parse DataChunk failed. OP_PUSHDATA2 error") } - _ = scriptData.withUnsafeBytes { - memcpy(&dataLength, $0 + offset + MemoryLayout.size(ofValue: opcode), MemoryLayout.size(ofValue: dataLength)) + dataSize = scriptData.withUnsafeBytes { + Int( + CFSwapInt16LittleToHost( + $0.load(fromByteOffset: offset + opCodeSize, as: UInt16.self) + ) + ) } - dataLength = CFSwapInt16LittleToHost(dataLength) - chunkLength = MemoryLayout.size(ofValue: opcode) + MemoryLayout.size(ofValue: dataLength) + Int(dataLength) case OpCode.OP_PUSHDATA4.value: - var dataLength = UInt32() - guard offset + MemoryLayout.size(ofValue: dataLength) <= count else { - throw ScriptChunkError.error("Parse DataChunk failed. OP_PUSHDATA4 error") + dataLengthSize = MemoryLayout.size + guard offset + opCodeSize + dataLengthSize <= count else { + throw ScriptChunkError.error("Parse DataChunk failed. OP_PUSHDATA4 error") } - _ = scriptData.withUnsafeBytes { - memcpy(&dataLength, $0 + offset + MemoryLayout.size(ofValue: opcode), MemoryLayout.size(ofValue: dataLength)) + dataSize = scriptData.withUnsafeBytes { + Int( + CFSwapInt32LittleToHost( + $0.load(fromByteOffset: offset + opCodeSize, as: UInt32.self) + ) + ) } - dataLength = CFSwapInt32LittleToHost(dataLength) // CoreBitcoin uses CFSwapInt16LittleToHost(dataLength) - chunkLength = MemoryLayout.size(ofValue: opcode) + MemoryLayout.size(ofValue: dataLength) + Int(dataLength) default: // cannot happen because it's opcode throw ScriptChunkError.error("Parse DataChunk failed. OP_CODE: \(opcode).") diff --git a/Sources/BitcoinKit/Scripts/ScriptExecutionContext.swift b/Sources/BitcoinKit/Scripts/ScriptExecutionContext.swift index d927eac5..423e5aea 100644 --- a/Sources/BitcoinKit/Scripts/ScriptExecutionContext.swift +++ b/Sources/BitcoinKit/Scripts/ScriptExecutionContext.swift @@ -54,7 +54,7 @@ public class ScriptExecutionContext { // Constants private let blobFalse: Data = Data() private let blobZero: Data = Data() - private let blobTrue: Data = Data(bytes: [UInt8(1)]) + private let blobTrue: Data = Data([UInt8(1)]) // If verbose is true, stack will be printed each time OP_CODEs are executed public var verbose: Bool = false