diff --git a/BitcoinKit.xcodeproj/project.pbxproj b/BitcoinKit.xcodeproj/project.pbxproj index 61e72135..3950ec89 100644 --- a/BitcoinKit.xcodeproj/project.pbxproj +++ b/BitcoinKit.xcodeproj/project.pbxproj @@ -59,6 +59,7 @@ 0C2375A52132507B00DB2872 /* MessageSerializerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C2375A32132501700DB2872 /* MessageSerializerTests.swift */; }; 0C2CB94D211FAD320087A8EB /* OP_BIN2NUM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C2CB94C211FAD320087A8EB /* OP_BIN2NUM.swift */; }; 0C4132EF210EFD1700906E4A /* OP_SWAP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C4132EE210EFD1700906E4A /* OP_SWAP.swift */; }; + 0C61BF51215B988A001415CA /* Encoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C61BF50215B988A001415CA /* Encoding.swift */; }; 0C66CD032125425D0049DB89 /* OP_INVERT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C66CD022125425D0049DB89 /* OP_INVERT.swift */; }; 0C66CD05212542660049DB89 /* OP_AND.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C66CD04212542660049DB89 /* OP_AND.swift */; }; 0C66CD07212542730049DB89 /* OP_OR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C66CD06212542730049DB89 /* OP_OR.swift */; }; @@ -75,7 +76,6 @@ 147494D6201F9A29006D1CF8 /* BitcoinKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 147494D5201F9A29006D1CF8 /* BitcoinKitTests.swift */; }; 147494D8201F9A29006D1CF8 /* BitcoinKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 147494CA201F9A29006D1CF8 /* BitcoinKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 147494E4201F9B85006D1CF8 /* Crypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 147494E3201F9B85006D1CF8 /* Crypto.swift */; }; - 147494E6201F9BF0006D1CF8 /* Encoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 147494E5201F9BEF006D1CF8 /* Encoding.swift */; }; 147494EC201F9E4F006D1CF8 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 147494EB201F9E4F006D1CF8 /* Network.swift */; }; 147494EE201FADAC006D1CF8 /* MurmurHash.swift in Sources */ = {isa = PBXBuildFile; fileRef = 147494ED201FADAC006D1CF8 /* MurmurHash.swift */; }; 147494F0201FAE30006D1CF8 /* Serialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 147494EF201FAE30006D1CF8 /* Serialization.swift */; }; @@ -161,7 +161,6 @@ 2949920220F228B400D078B6 /* UnspentTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2949920120F228B400D078B6 /* UnspentTransaction.swift */; }; 2949920420F22A1500D078B6 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2949920320F22A1500D078B6 /* TestHelpers.swift */; }; 2949920620F22DCA00D078B6 /* UnsignedTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2949920520F22DCA00D078B6 /* UnsignedTransaction.swift */; }; - 294D6CB6215A124700B75928 /* SerializationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294D6CB5215A124700B75928 /* SerializationTests.swift */; }; 294DDE32211A05D200B7F645 /* OP_RETURN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294DDE31211A05D200B7F645 /* OP_RETURN.swift */; }; 294DDE3B211B31B100B7F645 /* OP_NOP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294DDE3A211B31B100B7F645 /* OP_NOP.swift */; }; 294DDE3D211B31C100B7F645 /* OP_VER.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294DDE3C211B31C100B7F645 /* OP_VER.swift */; }; @@ -210,6 +209,17 @@ 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 */; }; + 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 */; }; + A2613884211E8E12003A3B29 /* UInt256+Bitcoin.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2613883211E8E12003A3B29 /* UInt256+Bitcoin.swift */; }; + A29721F8211B2497007228D5 /* Math.swift in Sources */ = {isa = PBXBuildFile; fileRef = A29721F7211B2497007228D5 /* Math.swift */; }; + A2B7A34E2125464400764AE9 /* ProofOfWork.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2B7A34D2125464400764AE9 /* ProofOfWork.swift */; }; + A2DAA5F7211F0579009DAB7B /* UInt32MathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2DAA5F6211F0579009DAB7B /* UInt32MathTests.swift */; }; + A2DAA5F9211F2C93009DAB7B /* SerializationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2DAA5F8211F2C93009DAB7B /* SerializationTests.swift */; }; + 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 */; }; 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 */; }; @@ -285,6 +295,7 @@ 0C2375A32132501700DB2872 /* MessageSerializerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSerializerTests.swift; sourceTree = ""; }; 0C2CB94C211FAD320087A8EB /* OP_BIN2NUM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OP_BIN2NUM.swift; sourceTree = ""; }; 0C4132EE210EFD1700906E4A /* OP_SWAP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OP_SWAP.swift; sourceTree = ""; }; + 0C61BF50215B988A001415CA /* Encoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Encoding.swift; path = Keys/Encoding.swift; sourceTree = ""; }; 0C66CD022125425D0049DB89 /* OP_INVERT.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OP_INVERT.swift; sourceTree = ""; }; 0C66CD04212542660049DB89 /* OP_AND.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OP_AND.swift; sourceTree = ""; }; 0C66CD06212542730049DB89 /* OP_OR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OP_OR.swift; sourceTree = ""; }; @@ -306,7 +317,6 @@ 147494D5201F9A29006D1CF8 /* BitcoinKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitcoinKitTests.swift; sourceTree = ""; }; 147494D7201F9A29006D1CF8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 147494E3201F9B85006D1CF8 /* Crypto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Crypto.swift; sourceTree = ""; }; - 147494E5201F9BEF006D1CF8 /* Encoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encoding.swift; sourceTree = ""; }; 147494EB201F9E4F006D1CF8 /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = ""; }; 147494ED201FADAC006D1CF8 /* MurmurHash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MurmurHash.swift; sourceTree = ""; }; 147494EF201FAE30006D1CF8 /* Serialization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Serialization.swift; sourceTree = ""; }; @@ -391,7 +401,6 @@ 2949920120F228B400D078B6 /* UnspentTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnspentTransaction.swift; sourceTree = ""; }; 2949920320F22A1500D078B6 /* TestHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = ""; }; 2949920520F22DCA00D078B6 /* UnsignedTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsignedTransaction.swift; sourceTree = ""; }; - 294D6CB5215A124700B75928 /* SerializationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerializationTests.swift; sourceTree = ""; }; 294DDE31211A05D200B7F645 /* OP_RETURN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OP_RETURN.swift; sourceTree = ""; }; 294DDE3A211B31B100B7F645 /* OP_NOP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OP_NOP.swift; sourceTree = ""; }; 294DDE3C211B31C100B7F645 /* OP_VER.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OP_VER.swift; sourceTree = ""; }; @@ -441,6 +450,17 @@ 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 = ""; }; + 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 = ""; }; + A2613883211E8E12003A3B29 /* UInt256+Bitcoin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt256+Bitcoin.swift"; sourceTree = ""; }; + A29721F7211B2497007228D5 /* Math.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Math.swift; sourceTree = ""; }; + A2B7A34D2125464400764AE9 /* ProofOfWork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProofOfWork.swift; sourceTree = ""; }; + A2DAA5F6211F0579009DAB7B /* UInt32MathTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UInt32MathTests.swift; sourceTree = ""; }; + A2DAA5F8211F2C93009DAB7B /* SerializationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerializationTests.swift; sourceTree = ""; }; + 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 = ""; }; 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 = ""; }; @@ -587,7 +607,11 @@ 6E20AED62112D417008A9810 /* MurmurHashTests.swift */, 6E797C442116C8A5003BEDFD /* OpCodeFactoryTests.swift */, 29089F0D2122BE7200E0C305 /* MockHelperTests.swift */, - 294D6CB5215A124700B75928 /* SerializationTests.swift */, + A20B537E211C72F9009D147A /* UInt256Tests.swift */, + A2DAA5F6211F0579009DAB7B /* UInt32MathTests.swift */, + A2DAA5F8211F2C93009DAB7B /* SerializationTests.swift */, + A2DE510F212AFCF200F54EA0 /* UInt256+BitcoinTests.swift */, + A2E11230212C400A00A0A40A /* ProofOfWorkTests.swift */, ); name = BitcoinKitTests; path = Tests/BitcoinKitTests; @@ -642,12 +666,19 @@ 1482B5E32026F2580098B612 /* WordList.swift */, 14839A7B202F79F900A6CB34 /* PaymentURI.swift */, 147494E3201F9B85006D1CF8 /* Crypto.swift */, + 0C61BF50215B988A001415CA /* Encoding.swift */, + A29721F7211B2497007228D5 /* Math.swift */, + A246ED0F2118621B0000418D /* MerkleTree.swift */, + A2B7A34D2125464400764AE9 /* ProofOfWork.swift */, 147494EF201FAE30006D1CF8 /* Serialization.swift */, 14F37A3D2020A02000D34748 /* SighashType.swift */, 29330F6D210597B700106AFA /* UnitsAndLimits.swift */, 299CB47220F0185500B1245C /* TransactionSignatureSerializer.swift */, 299CB46E20EE1EA500B1245C /* Transaction+SignatureHash.swift */, 2949920120F228B400D078B6 /* UnspentTransaction.swift */, + A2F06FB92126785200DFF652 /* UInt32+Utility.swift */, + A246ED11211864500000418D /* UInt256.swift */, + A2613883211E8E12003A3B29 /* UInt256+Bitcoin.swift */, 2949920520F22DCA00D078B6 /* UnsignedTransaction.swift */, 14839AA4202FE7A100A6CB34 /* ByteStream.swift */, 147F9728201FC89E0071F49D /* BloomFilter.swift */, @@ -888,7 +919,6 @@ 1482B5E7202721FF0098B612 /* HDPrivateKey.swift */, 1482B5E920273B8A0098B612 /* HDPublicKey.swift */, 14CDC3892021881A00C01556 /* Address.swift */, - 147494E5201F9BEF006D1CF8 /* Encoding.swift */, 294991FF20F227EB00D078B6 /* VersionByte.swift */, 297DB97220EB12E60077EEEE /* AddressType.swift */, 297DB97420EB13320077EEEE /* AddressFactory.swift */, @@ -1056,7 +1086,6 @@ 14839A9D202FE72600A6CB34 /* TransactionOutPoint.swift in Sources */, 2933014D214FCE150028946B /* TransactionHistoryProvider.swift in Sources */, 0C1DE155211D787100FE8E43 /* OP_TOTALSTACK.swift in Sources */, - 147494E6201F9BF0006D1CF8 /* Encoding.swift in Sources */, 2949920220F228B400D078B6 /* UnspentTransaction.swift in Sources */, 0C0900442116BA8F0077E9BC /* OP_RSHIFT.swift in Sources */, 14839A7F202FE58800A6CB34 /* VersionMessage.swift in Sources */, @@ -1107,6 +1136,7 @@ 29E1ED75210EF071007F4627 /* OP_CHECKMULTISIGVERIFY.swift in Sources */, 294DDE3F211B31CB00B7F645 /* OP_IF.swift in Sources */, 29290B8D210AF59600D2BE78 /* OpCodeFactory.swift in Sources */, + A246ED102118621B0000418D /* MerkleTree.swift in Sources */, 147F9729201FC89E0071F49D /* BloomFilter.swift in Sources */, 0C1DD40A211819CE004BA8A8 /* OP_GREATERTHAN.swift in Sources */, 2914BE49211BAB1900B349CB /* OP_CODESEPARATOR.swift in Sources */, @@ -1115,12 +1145,15 @@ 2914BE52211BCF9600B349CB /* OP_RESERVED2.swift in Sources */, 0C66CD05212542660049DB89 /* OP_AND.swift in Sources */, 0C1DD41021181AF3004BA8A8 /* OP_NUMEQUAL.swift in Sources */, + A2613884211E8E12003A3B29 /* UInt256+Bitcoin.swift in Sources */, 14839AA9202FE7DD00A6CB34 /* VarString.swift in Sources */, 14F37A3E2020A02000D34748 /* SighashType.swift in Sources */, + A2F06FBA2126785200DFF652 /* UInt32+Utility.swift in Sources */, 14839A8F202FE68000A6CB34 /* PongMessage.swift in Sources */, 294DDE41211B31D600B7F645 /* OP_NOTIF.swift in Sources */, 0C1DE161211E717500FE8E43 /* OP_OVER.swift in Sources */, 0C1DD42321182126004BA8A8 /* OP_MOD.swift in Sources */, + A29721F8211B2497007228D5 /* Math.swift in Sources */, 29290B9B210AF88C00D2BE78 /* OP_HASH160.swift in Sources */, 14CDC3862021824200C01556 /* Wallet.swift in Sources */, 0C1DE165211E75A800FE8E43 /* OP_ROLL.swift in Sources */, @@ -1143,6 +1176,7 @@ 29248EEF2104B64E00CC9051 /* ScriptChunkHelper.swift in Sources */, 14839A85202FE60E00A6CB34 /* InventoryMessage.swift in Sources */, 14839AA7202FE7C700A6CB34 /* VarInt.swift in Sources */, + 0C61BF51215B988A001415CA /* Encoding.swift in Sources */, 29E1ED73210ECD35007F4627 /* OP_CHECKMULTISIG.swift in Sources */, 29290B99210AF88400D2BE78 /* OP_EQUALVERIFY.swift in Sources */, 294DDE47211B322000B7F645 /* OP_ELSE.swift in Sources */, @@ -1159,7 +1193,9 @@ 147494E4201F9B85006D1CF8 /* Crypto.swift in Sources */, 2933014F214FCE2D0028946B /* TransactionBroadcaster.swift in Sources */, 0C0900422116B9DE0077E9BC /* OP_LSHIFT.swift in Sources */, + A2B7A34E2125464400764AE9 /* ProofOfWork.swift in Sources */, 14839A9F202FE73B00A6CB34 /* TransactionOutput.swift in Sources */, + A246ED12211864500000418D /* UInt256.swift in Sources */, 1463E6B62025E99C0033DAAE /* BlockChain.swift in Sources */, 2914BE4E211BCF7600B349CB /* OP_RESERVED.swift in Sources */, 14839A81202FE5CA00A6CB34 /* VerackMessage.swift in Sources */, @@ -1236,6 +1272,7 @@ buildActionMask = 2147483647; files = ( 147494D6201F9A29006D1CF8 /* BitcoinKitTests.swift in Sources */, + A2DE5110212AFCF200F54EA0 /* UInt256+BitcoinTests.swift in Sources */, CFA290742102B650001A1BAB /* ScriptMachineTests.swift in Sources */, 6E20AECB2112C434008A9810 /* HDPrivateKeyTests.swift in Sources */, 6E20AED52112C8F9008A9810 /* BloomFilterTests.swift in Sources */, @@ -1249,18 +1286,21 @@ 6E797C452116C8A5003BEDFD /* OpCodeFactoryTests.swift in Sources */, CF432AFC20F25E0000AD4020 /* TestHelpersTests.swift in Sources */, 0C2375A52132507B00DB2872 /* MessageSerializerTests.swift in Sources */, + A2E11231212C400A00A0A40A /* ProofOfWorkTests.swift in Sources */, CFA290702101CDCA001A1BAB /* ScriptTests.swift in Sources */, 6E20AECF2112C66C008A9810 /* HDKeyChainTests.swift in Sources */, CF432AF420F0DFAC00AD4020 /* Bech32Tests.swift in Sources */, 29089F0E2122BE7200E0C305 /* MockHelperTests.swift in Sources */, 6E20AECD2112C559008A9810 /* CashAddrTests.swift in Sources */, + A2DAA5F7211F0579009DAB7B /* UInt32MathTests.swift in Sources */, 29F5D1E02110495F007DA3BF /* OpCodeTests.swift in Sources */, 6E20AEC92112C31A008A9810 /* LegacyAddressTests.swift in Sources */, 6E20AED12112C6AA008A9810 /* PaymentURITests.swift in Sources */, - 294D6CB6215A124700B75928 /* SerializationTests.swift in Sources */, CF432AF220F0CF9100AD4020 /* Base58Tests.swift in Sources */, + A2DAA5F9211F2C93009DAB7B /* SerializationTests.swift in Sources */, 2949920420F22A1500D078B6 /* TestHelpers.swift in Sources */, 29F5D1E421106772007DA3BF /* BigNumberTests.swift in Sources */, + A20B537F211C72F9009D147A /* UInt256Tests.swift in Sources */, 0F59D2EC213712B2008B9C0B /* BlockMessageTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/BitcoinKit.xcodeproj/xcshareddata/xcschemes/BitcoinKit.xcscheme b/BitcoinKit.xcodeproj/xcshareddata/xcschemes/BitcoinKit.xcscheme index 4bb67004..1aa33740 100644 --- a/BitcoinKit.xcodeproj/xcshareddata/xcschemes/BitcoinKit.xcscheme +++ b/BitcoinKit.xcodeproj/xcshareddata/xcschemes/BitcoinKit.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + codeCoverageEnabled = "YES" shouldUseLaunchSchemeArgsEnv = "YES"> UInt32 { + if x == 0 { return 0 } + guard x > 1 else { return 0 } + var xx: UInt32 = x - 1 + var r: UInt32 = 0 + while xx > 0 { + xx >>= 1 + r += 1 + } + return r +} diff --git a/Sources/BitcoinKit/Core/MerkleTree.swift b/Sources/BitcoinKit/Core/MerkleTree.swift new file mode 100644 index 00000000..58a0de72 --- /dev/null +++ b/Sources/BitcoinKit/Core/MerkleTree.swift @@ -0,0 +1,95 @@ +// +// MerkleTree.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +struct MerkleTree { + enum MerkleError: Error { + case noEnoughParent + case noEnoughHash + case duplicateHash // CVE-2012-2459 + case invalidNumberOfHashes + case invalidNumberOfFlags + case nullHash + } + + static func buildMerkleRoot(numberOfHashes: UInt32, hashes: [Data], numberOfFlags: UInt32, flags: [UInt8], totalTransactions: UInt32) throws -> Data { + if numberOfHashes != hashes.count { + throw MerkleError.invalidNumberOfHashes + } + if flags.count < numberOfFlags / 8 { + throw MerkleError.invalidNumberOfFlags + } + let parents: [Bool] = (0 ..< Int(numberOfFlags)).compactMap({ + return (flags[$0 / 8] & UInt8(1 << ($0 % 8))) != 0 + }) + let maxdepth: UInt = UInt(ceil_log2(totalTransactions)) + var hashIterator = hashes.makeIterator() + var parentIterator = parents.makeIterator() + let root = try buildPartialMerkleTree(hashIterator: &hashIterator, parentIterator: &parentIterator, depth: 0, maxdepth: maxdepth) + guard let h = root.hash else { throw MerkleError.nullHash } + return h + } + + struct PartialMerkleTree { + var hash: Data? + // zero size if depth is maxdepth + // leaf[0]: left, leaf[1]: right + var leaf: [PartialMerkleTree] = [] + init(hash: Data, leafL: PartialMerkleTree, leafR: PartialMerkleTree) { + self.hash = hash + leaf.append(leafL) + leaf.append(leafR) + } + init(hash: Data) { + self.hash = hash + } + } + + private static func buildPartialMerkleTree( + hashIterator: inout IndexingIterator<[Data]>, + parentIterator: inout IndexingIterator<[Bool]>, + depth: UInt, maxdepth: UInt) throws -> PartialMerkleTree { + guard let parent = parentIterator.next() else { throw MerkleError.noEnoughParent } + if !parent || maxdepth <= depth { + // leaf + guard let hash = hashIterator.next() else { throw MerkleError.noEnoughHash } + return PartialMerkleTree(hash: hash) + } else { + // vertex + let left: PartialMerkleTree = try buildPartialMerkleTree(hashIterator: &hashIterator, parentIterator: &parentIterator, depth: depth + 1, maxdepth: maxdepth) + let right: PartialMerkleTree = try buildPartialMerkleTree(hashIterator: &hashIterator, parentIterator: &parentIterator, depth: depth + 1, maxdepth: maxdepth) + if let h0 = left.hash, let h1 = right.hash { + if h0 == h1 { + // CVE-2012-2459 + throw MerkleError.duplicateHash + } + let hash = Crypto.sha256sha256(h0 + h1) + return PartialMerkleTree(hash: hash, leafL: left, leafR: right) + } else { + throw MerkleError.nullHash + } + } + } +} diff --git a/Sources/BitcoinKit/Core/ProofOfWork.swift b/Sources/BitcoinKit/Core/ProofOfWork.swift new file mode 100644 index 00000000..6fc96952 --- /dev/null +++ b/Sources/BitcoinKit/Core/ProofOfWork.swift @@ -0,0 +1,56 @@ +// +// ProofOfWork.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +class ProofOfWork { + static let maxProofOfWork: UInt256 + = UInt256(data: Data(hex: "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff")!)! + static func isValidProofOfWork(blockHash: Data, bits: UInt32) -> Bool { + let target: UInt256 + do { + target = try UInt256(compact: bits) + } catch { + // invalid bits + return false + } + guard target != UInt256.zero else { + // invalid zero target + return false + } + guard target <= maxProofOfWork else { + // too high target + return false + } + guard let arith_hash = UInt256(data: blockHash) else { + // invalid blockHash data length + return false + } + guard arith_hash <= target else { + // insufficient proof of work + return false + } + return true + } +} diff --git a/Sources/BitcoinKit/Core/UInt256+Bitcoin.swift b/Sources/BitcoinKit/Core/UInt256+Bitcoin.swift new file mode 100644 index 00000000..a88e31d8 --- /dev/null +++ b/Sources/BitcoinKit/Core/UInt256+Bitcoin.swift @@ -0,0 +1,52 @@ +// +// UInt256+Bitcoin.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +extension UInt256 { + public enum CompactError: Error { + case negative, overflow + } + // bitcoin "compact" format + public init(compact: UInt32) throws { + let size: UInt32 = compact >> 24 + let target: UInt32 = compact & 0x007fffff + if target == 0 { + self = UInt256.zero + } else { + // The 0x00800000 denotes the sign + if (compact & 0x00800000) != 0 { + throw CompactError.negative + } + if size > 0x22 || (target > 0xff && size > 0x21) || (target > 0xffff && size > 0x20) { + throw CompactError.overflow + } + if size < 3 { + self = UInt256(target) >> ((3 - size) * 8) + } else { + self = UInt256(target) << ((size - 3) * 8) + } + } + } +} diff --git a/Sources/BitcoinKit/Core/UInt256.swift b/Sources/BitcoinKit/Core/UInt256.swift new file mode 100644 index 00000000..89a7a280 --- /dev/null +++ b/Sources/BitcoinKit/Core/UInt256.swift @@ -0,0 +1,261 @@ +// +// UInt256.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +// UInt256 corresponds to `arith_uint256` in the original bitcoin core. +struct UInt256 { + enum UInt256Error: Error { + case invalidDataSize + } + public static var max: UInt256 { + return UInt256(UInt64.max, UInt64.max, UInt64.max, UInt64.max) + } + public static var bitWidth: Int { return 256 } + public static let byteWidth = UInt256.bitWidth / 8 + static let elementCount = byteWidth / 8 + + // e0 is lowest digit (UInt64 value is LittleEndian) + // e3 is highest digit (UInt64 value is LittleEndian) + private var e0: UInt64 + private var e1: UInt64 + private var e2: UInt64 + private var e3: UInt64 + + public static let zero = UInt256() + + init() { + e0 = 0 + e1 = 0 + e2 = 0 + e3 = 0 + } + + init(_ e0: UInt64, _ e1: UInt64, _ e2: UInt64, _ e3: UInt64) { + self.e0 = e0 + self.e1 = e1 + self.e2 = e2 + self.e3 = e3 + } + + // 64bytes "01 00 00 00 ... 00" + // : UInt256(1) + init?(data: Data) { + if data.count != UInt256.byteWidth { return nil } + // little endian cast + e0 = data[0..<8].to(type: UInt64.self) + e1 = data[8..<16].to(type: UInt64.self) + e2 = data[16..<24].to(type: UInt64.self) + e3 = data[24..<32].to(type: UInt64.self) + } + + // hex: MSB representation + // "_" is ignored in parsing + // UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001") + // : UInt256(1) + init?(hex: String) { + let h = hex.replacingOccurrences(of: "_", with: "") + // big endian + guard let data = Data(hex: h)?.reversed() else { return nil } + self.init(data: Data(data)) + } + + public init(_ val: UInt) { + // set to lowest digit + self = UInt256(UInt64(val), 0, 0, 0) + } + + public init(_ val: UInt64) { + self = UInt256(val, 0, 0, 0) + } + + public init(_ val: UInt32) { + self = UInt256(UInt64(val)) + } + + public init(_ val: UInt16) { + self = UInt256(UInt64(val)) + } + + public init(_ val: UInt8) { + self = UInt256(UInt64(val)) + } +} + +extension UInt256: CustomDebugStringConvertible { + public var debugDescription: String { + return self.hex + } +} + +extension UInt256: Equatable { + public static func == (lhs: UInt256, rhs: UInt256) -> Bool { + if lhs.e0 != rhs.e0 { + return false + } else if lhs.e1 != rhs.e1 { + return false + } else if lhs.e2 != rhs.e2 { + return false + } else if lhs.e3 != rhs.e3 { + return false + } + return true + } +} + +extension UInt256: Comparable { + public static func < (lhs: UInt256, rhs: UInt256) -> Bool { + // compare higest digit at first + if lhs.e3 != rhs.e3 { + return lhs.e3 < rhs.e3 + } else if lhs.e2 != rhs.e2 { + return lhs.e2 < rhs.e2 + } else if lhs.e1 != rhs.e1 { + return lhs.e1 < rhs.e1 + } else if lhs.e0 != rhs.e0 { + return lhs.e0 < rhs.e0 + } + // a < a is always false (Irreflexivity) + return false + } +} + +extension UInt64 { + // MSB representation + public var hex: String { + let high: UInt64 = (self & 0xffffffff00000000) >> 32 + let low: UInt64 = self & 0x00000000ffffffff + return String(format: "%08x", high) + String(format: "%08x", low) + } +} + +extension UInt256 { + // MSB representation + public var hex: String { + return [e3, e2, e1, e0].map({ $0.hex }).joined(separator: "") + } +} + +extension UInt256 { + public var data: Data { + // little endian cast + return Data(from: e0) + Data(from: e1) + Data(from: e2) + Data(from: e3) + } +} + +protocol BitShiftOperator { + static func >> (lhs: Self, rhs: RHS) -> Self where RHS: UnsignedInteger + static func << (lhs: Self, rhs: RHS) -> Self where RHS: UnsignedInteger +} + +extension UInt256: BitShiftOperator { + public static func >> (lhs: UInt256, rhs: RHS) -> UInt256 where RHS: UnsignedInteger { + if rhs < 64 { + var v = UInt256() + let mask = bitValue(bit: UInt(rhs)) + let shift = 64 - rhs + v.e3 = lhs.e3 >> rhs + v.e2 = (lhs.e2 >> rhs) + ((lhs.e3 & mask) << shift) + v.e1 = (lhs.e1 >> rhs) + ((lhs.e2 & mask) << shift) + v.e0 = (lhs.e0 >> rhs) + ((lhs.e1 & mask) << shift) + return v + } else if rhs < 128 { + var v = UInt256() + let mask = bitValue(bit: UInt(rhs - 64)) + let shift = 128 - rhs + v.e3 = 0 + v.e2 = (lhs.e3 >> (rhs - 64)) + v.e1 = (lhs.e2 >> (rhs - 64)) + ((lhs.e3 & mask) << shift) + v.e0 = (lhs.e1 >> (rhs - 64)) + ((lhs.e2 & mask) << shift) + return v + } else if rhs < 192 { + var v = UInt256() + let mask = bitValue(bit: UInt(rhs - 128)) + let shift = 192 - rhs + v.e3 = 0 + v.e2 = 0 + v.e1 = (lhs.e3 >> (rhs - 128)) + v.e0 = (lhs.e2 >> (rhs - 128)) + ((lhs.e3 & mask) << shift) + return v + } else if rhs < 256 { + var v = UInt256() + v.e3 = 0 + v.e2 = 0 + v.e1 = 0 + v.e0 = (lhs.e3 >> (rhs - 192)) + return v + } else { + return UInt256.zero + } + } + + public static func << (lhs: UInt256, rhs: RHS) -> UInt256 where RHS: UnsignedInteger { + if rhs < 64 { + var v = UInt256() + let rev = rhs + let shift = 64 - rhs + v.e3 = (lhs.e3 << rev) + (lhs.e2 >> shift) + v.e2 = (lhs.e2 << rev) + (lhs.e1 >> shift) + v.e1 = (lhs.e1 << rev) + (lhs.e0 >> shift) + v.e0 = (lhs.e0 << rev) + return v + } else if rhs < 128 { + var v = UInt256() + let rev = rhs - 64 + let shift = 128 - rhs + v.e3 = (lhs.e2 << rev) + (lhs.e1 >> shift) + v.e2 = (lhs.e1 << rev) + (lhs.e0 >> shift) + v.e1 = (lhs.e0 << rev) + v.e0 = 0 + return v + } else if rhs < 192 { + var v = UInt256() + let rev = rhs - 128 + let shift = 192 - rhs + v.e3 = (lhs.e1 << rev) + (lhs.e0 >> shift) + v.e2 = (lhs.e0 << rev) + v.e1 = 0 + v.e0 = 0 + return v + } else if rhs < 256 { + var v = UInt256() + let rev = rhs - 192 + v.e3 = (lhs.e0 << rev) + v.e2 = 0 + v.e1 = 0 + v.e0 = 0 + return v + } else { + return UInt256.zero + } + } +} + +private func bitValue(bit: UInt) -> UInt64 { + var v: UInt64 = 0 + for i in 0 ..< bit { + v += (1 << i) + } + return v +} diff --git a/Sources/BitcoinKit/Core/UInt32+Utility.swift b/Sources/BitcoinKit/Core/UInt32+Utility.swift new file mode 100644 index 00000000..ea7e6528 --- /dev/null +++ b/Sources/BitcoinKit/Core/UInt32+Utility.swift @@ -0,0 +1,31 @@ +// +// UInt32+Utility.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +extension UInt32 { + public var hex: String { + return String(format: "%08x", self) + } +} diff --git a/Sources/BitcoinKit/Networking/PeerGroup.swift b/Sources/BitcoinKit/Networking/PeerGroup.swift index b57e5c40..ea8cf462 100644 --- a/Sources/BitcoinKit/Networking/PeerGroup.swift +++ b/Sources/BitcoinKit/Networking/PeerGroup.swift @@ -103,6 +103,24 @@ public class PeerGroup: PeerDelegate { } public func peer(_ peer: Peer, didReceiveMerkleBlockMessage message: MerkleBlockMessage, hash: Data) { + guard ProofOfWork.isValidProofOfWork(blockHash: hash, bits: message.bits) else { + print("insufficient proof of work!") + return + } + do { + let root: Data = try MerkleTree.buildMerkleRoot(numberOfHashes: UInt32(message.numberOfHashes.underlyingValue), + hashes: message.hashes, + numberOfFlags: UInt32(message.numberOfFlags.underlyingValue), + flags: message.flags, + totalTransactions: message.totalTransactions) + if root != message.merkleRoot { + print("not match merkelroot!") + return + } + } catch { + print("merkleroot build failed!") + return + } try! blockChain.addMerkleBlock(message, hash: hash) } diff --git a/Tests/BitcoinKitTests/ProofOfWorkTests.swift b/Tests/BitcoinKitTests/ProofOfWorkTests.swift new file mode 100644 index 00000000..0d4cf6db --- /dev/null +++ b/Tests/BitcoinKitTests/ProofOfWorkTests.swift @@ -0,0 +1,43 @@ +// +// ProofOfWorkTests.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import XCTest +@testable import BitcoinKit + +class ProofOfWorkTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testExample() { + // TODO: + } + + +} diff --git a/Tests/BitcoinKitTests/SerializationTests.swift b/Tests/BitcoinKitTests/SerializationTests.swift index 4ca835ed..2e0a84bb 100644 --- a/Tests/BitcoinKitTests/SerializationTests.swift +++ b/Tests/BitcoinKitTests/SerializationTests.swift @@ -26,6 +26,33 @@ import XCTest @testable import BitcoinKit class SerializationTests: XCTestCase { + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testUInt32toHex() { + let d = Data(bytes: [1, 2, 3, 4]) + let i: UInt32 = d.to(type: UInt32.self) + XCTAssertEqual(i.hex, "04030201") + XCTAssertEqual(i, 0x04030201) + } + + func testUInt64toHex() { + let d = Data(bytes: [1, 2, 3, 4, 5, 6, 7, 8]) + let i: UInt64 = d.to(type: UInt64.self) + XCTAssertEqual(i.hex, "0807060504030201") + XCTAssertEqual(i, 0x0807060504030201) + } + + func testDataToUInt256() { + let d = Data(bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]) + let i: UInt256 = d.to(type: UInt256.self) + XCTAssertEqual(i.hex, "0200000000000000000000000000000000000000000000000000000000000001") + } func testDataToInt32() { for _ in 0..<10 { @@ -36,5 +63,4 @@ class SerializationTests: XCTestCase { } } } - } diff --git a/Tests/BitcoinKitTests/UInt256+BitcoinTests.swift b/Tests/BitcoinKitTests/UInt256+BitcoinTests.swift new file mode 100644 index 00000000..a0cf66d5 --- /dev/null +++ b/Tests/BitcoinKitTests/UInt256+BitcoinTests.swift @@ -0,0 +1,123 @@ +// +// UInt256+BitcoinTests.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import XCTest +@testable import BitcoinKit + +class UInt256_BitcoinTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func test1() { + // size = 0 + XCTAssertEqual(try UInt256(compact: 0x007fffff as UInt32).hex, "0000000000000000000000000000000000000000000000000000000000000000") + // target -0 + XCTAssertEqual(try UInt256(compact: 0x22800000 as UInt32).hex, "0000000000000000000000000000000000000000000000000000000000000000") + // target 0 + XCTAssertEqual(try UInt256(compact: 0x22000000 as UInt32).hex, "0000000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual(try UInt256(compact: 0x017fffff as UInt32).hex, "000000000000000000000000000000000000000000000000000000000000007f") + XCTAssertEqual(try UInt256(compact: 0x027fffff as UInt32).hex, "0000000000000000000000000000000000000000000000000000000000007fff") + XCTAssertEqual(try UInt256(compact: 0x03123456 as UInt32).hex, "0000000000000000000000000000000000000000000000000000000000123456") + XCTAssertEqual(try UInt256(compact: 0x037fffff as UInt32).hex, "00000000000000000000000000000000000000000000000000000000007fffff") + XCTAssertEqual(try UInt256(compact: 0x047fffff as UInt32).hex, "000000000000000000000000000000000000000000000000000000007fffff00") + XCTAssertEqual(try UInt256(compact: 0x057fffff as UInt32).hex, "0000000000000000000000000000000000000000000000000000007fffff0000") + XCTAssertEqual(try UInt256(compact: 0x067fffff as UInt32).hex, "00000000000000000000000000000000000000000000000000007fffff000000") + XCTAssertEqual(try UInt256(compact: 0x077fffff as UInt32).hex, "000000000000000000000000000000000000000000000000007fffff00000000") + XCTAssertEqual(try UInt256(compact: 0x087fffff as UInt32).hex, "0000000000000000000000000000000000000000000000007fffff0000000000") + XCTAssertEqual(try UInt256(compact: 0x097fffff as UInt32).hex, "00000000000000000000000000000000000000000000007fffff000000000000") + XCTAssertEqual(try UInt256(compact: 0x1d7fffff as UInt32).hex, "0000007fffff0000000000000000000000000000000000000000000000000000") + XCTAssertEqual(try UInt256(compact: 0x1e7fffff as UInt32).hex, "00007fffff000000000000000000000000000000000000000000000000000000") + XCTAssertEqual(try UInt256(compact: 0x1f7fffff as UInt32).hex, "007fffff00000000000000000000000000000000000000000000000000000000") + XCTAssertEqual(try UInt256(compact: 0x207fffff as UInt32).hex, "7fffff0000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual(try UInt256(compact: 0x2100ffff as UInt32).hex, "ffff000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual(try UInt256(compact: 0x220000ff as UInt32).hex, "ff00000000000000000000000000000000000000000000000000000000000000") + } + + func testOverflow() { + do { + _ = try UInt256(compact: 0x21010000 as UInt32) + XCTFail() + } catch UInt256.CompactError.overflow { + } catch { + XCTFail() + } + + do { + _ = try UInt256(compact: 0x22000100 as UInt32) + XCTFail() + } catch UInt256.CompactError.overflow { + } catch { + XCTFail() + } + + do { + _ = try UInt256(compact: 0x23000001 as UInt32) + XCTFail() + } catch UInt256.CompactError.overflow { + } catch { + XCTFail() + } + + do { + _ = try UInt256(compact: 0xff000001 as UInt32) + XCTFail() + } catch UInt256.CompactError.overflow { + } catch { + XCTFail() + } + } + + // negative + func testNegative() { + do { + _ = try UInt256(compact: 0x108fffff as UInt32) + XCTFail() + } catch UInt256.CompactError.negative { + } catch { + XCTFail() + } + + do { + _ = try UInt256(compact: 0x109fffff as UInt32) + XCTFail() + } catch UInt256.CompactError.negative { + } catch { + XCTFail() + } + + do { + _ = try UInt256(compact: 0x10ffffff as UInt32) + XCTFail() + } catch UInt256.CompactError.negative { + } catch { + XCTFail() + } + } +} diff --git a/Tests/BitcoinKitTests/UInt256Tests.swift b/Tests/BitcoinKitTests/UInt256Tests.swift new file mode 100644 index 00000000..6e7a1e9e --- /dev/null +++ b/Tests/BitcoinKitTests/UInt256Tests.swift @@ -0,0 +1,254 @@ +// +// UInt256Tests.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import XCTest +@testable import BitcoinKit + +class UInt256Tests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func test1() { + let v: UInt256 = UInt256(UInt(1592868)) << UInt(200) + XCTAssert(v != UInt256.zero) + } + + func testzero() { + let v: UInt256 = UInt256(UInt(0)) + XCTAssert(v == UInt256.zero) + } + + func testUInt64() { + XCTAssertEqual(UInt64(1).hex, "0000000000000001") + XCTAssertEqual(UInt64.max.hex, "ffffffffffffffff") + } + + func testUInt256() { + XCTAssertEqual(UInt256(UInt(1)).hex, "0000000000000000000000000000000000000000000000000000000000000001") + XCTAssertEqual(UInt256.max.hex, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + } + + func testUInt256ShiftLeft1() { + XCTAssertEqual((UInt256(UInt(1)) << UInt(0)).hex, "0000000000000000000000000000000000000000000000000000000000000001") + XCTAssertEqual((UInt256(UInt(1)) << UInt(1)).hex, "0000000000000000000000000000000000000000000000000000000000000002") + XCTAssertEqual((UInt256(UInt(1)) << UInt(2)).hex, "0000000000000000000000000000000000000000000000000000000000000004") + XCTAssertEqual((UInt256(UInt(1)) << UInt(3)).hex, "0000000000000000000000000000000000000000000000000000000000000008") + XCTAssertEqual((UInt256(UInt(1)) << UInt(4)).hex, "0000000000000000000000000000000000000000000000000000000000000010") + XCTAssertEqual((UInt256(UInt(1)) << UInt(5)).hex, "0000000000000000000000000000000000000000000000000000000000000020") + XCTAssertEqual((UInt256(UInt(1)) << UInt(6)).hex, "0000000000000000000000000000000000000000000000000000000000000040") + XCTAssertEqual((UInt256(UInt(1)) << UInt(7)).hex, "0000000000000000000000000000000000000000000000000000000000000080") + XCTAssertEqual((UInt256(UInt(1)) << UInt(8)).hex, "0000000000000000000000000000000000000000000000000000000000000100") + XCTAssertEqual((UInt256(UInt(1)) << UInt(9)).hex, "0000000000000000000000000000000000000000000000000000000000000200") + XCTAssertEqual((UInt256(UInt(1)) << UInt(10)).hex, "0000000000000000000000000000000000000000000000000000000000000400") + XCTAssertEqual((UInt256(UInt(1)) << UInt(11)).hex, "0000000000000000000000000000000000000000000000000000000000000800") + XCTAssertEqual((UInt256(UInt(1)) << UInt(12)).hex, "0000000000000000000000000000000000000000000000000000000000001000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(13)).hex, "0000000000000000000000000000000000000000000000000000000000002000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(14)).hex, "0000000000000000000000000000000000000000000000000000000000004000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(15)).hex, "0000000000000000000000000000000000000000000000000000000000008000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(16)).hex, "0000000000000000000000000000000000000000000000000000000000010000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(17)).hex, "0000000000000000000000000000000000000000000000000000000000020000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(18)).hex, "0000000000000000000000000000000000000000000000000000000000040000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(19)).hex, "0000000000000000000000000000000000000000000000000000000000080000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(20)).hex, "0000000000000000000000000000000000000000000000000000000000100000") + + XCTAssertEqual((UInt256(UInt(1)) << UInt(30)).hex, "0000000000000000000000000000000000000000000000000000000040000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(40)).hex, "0000000000000000000000000000000000000000000000000000010000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(50)).hex, "0000000000000000000000000000000000000000000000000004000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(60)).hex, "0000000000000000000000000000000000000000000000001000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(70)).hex, "0000000000000000000000000000000000000000000000400000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(80)).hex, "0000000000000000000000000000000000000000000100000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(90)).hex, "0000000000000000000000000000000000000000040000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(100)).hex, "0000000000000000000000000000000000000010000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(110)).hex, "0000000000000000000000000000000000004000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(120)).hex, "0000000000000000000000000000000001000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(130)).hex, "0000000000000000000000000000000400000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(140)).hex, "0000000000000000000000000000100000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(150)).hex, "0000000000000000000000000040000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(160)).hex, "0000000000000000000000010000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(170)).hex, "0000000000000000000004000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(180)).hex, "0000000000000000001000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(190)).hex, "0000000000000000400000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(200)).hex, "0000000000000100000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(210)).hex, "0000000000040000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(220)).hex, "0000000010000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(230)).hex, "0000004000000000000000000000000000000000000000000000000000000000") + + XCTAssertEqual((UInt256(UInt(1)) << UInt(240)).hex, "0001000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(241)).hex, "0002000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(242)).hex, "0004000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(243)).hex, "0008000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(244)).hex, "0010000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(245)).hex, "0020000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(246)).hex, "0040000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(247)).hex, "0080000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(248)).hex, "0100000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(249)).hex, "0200000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(250)).hex, "0400000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(251)).hex, "0800000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(252)).hex, "1000000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(253)).hex, "2000000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(254)).hex, "4000000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(255)).hex, "8000000000000000000000000000000000000000000000000000000000000000") + XCTAssertEqual((UInt256(UInt(1)) << UInt(256)).hex, "0000000000000000000000000000000000000000000000000000000000000000") + } + + func testUInt256ShiftRight1() { + XCTAssertEqual((UInt256.max >> UInt(0)).hex, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(1)).hex, "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(2)).hex, "3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(3)).hex, "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(4)).hex, "0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(5)).hex, "07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(6)).hex, "03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(7)).hex, "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(8)).hex, "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(9)).hex, "007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(10)).hex, "003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(11)).hex, "001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(12)).hex, "000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(13)).hex, "0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(14)).hex, "0003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(15)).hex, "0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(16)).hex, "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(17)).hex, "00007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(18)).hex, "00003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(19)).hex, "00001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(20)).hex, "00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + + XCTAssertEqual((UInt256.max >> UInt(30)).hex, "00000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(40)).hex, "0000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(50)).hex, "0000000000003fffffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(60)).hex, "000000000000000fffffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(70)).hex, "000000000000000003ffffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(80)).hex, "00000000000000000000ffffffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(90)).hex, "00000000000000000000003fffffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(100)).hex, "0000000000000000000000000fffffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(110)).hex, "0000000000000000000000000003ffffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(120)).hex, "000000000000000000000000000000ffffffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(130)).hex, "000000000000000000000000000000003fffffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(140)).hex, "00000000000000000000000000000000000fffffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(150)).hex, "00000000000000000000000000000000000003ffffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(160)).hex, "0000000000000000000000000000000000000000ffffffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(170)).hex, "0000000000000000000000000000000000000000003fffffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(180)).hex, "000000000000000000000000000000000000000000000fffffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(190)).hex, "000000000000000000000000000000000000000000000003ffffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(200)).hex, "00000000000000000000000000000000000000000000000000ffffffffffffff") + XCTAssertEqual((UInt256.max >> UInt(210)).hex, "00000000000000000000000000000000000000000000000000003fffffffffff") + XCTAssertEqual((UInt256.max >> UInt(220)).hex, "0000000000000000000000000000000000000000000000000000000fffffffff") + XCTAssertEqual((UInt256.max >> UInt(230)).hex, "0000000000000000000000000000000000000000000000000000000003ffffff") + + XCTAssertEqual((UInt256.max >> UInt(240)).hex, "000000000000000000000000000000000000000000000000000000000000ffff") + XCTAssertEqual((UInt256.max >> UInt(241)).hex, "0000000000000000000000000000000000000000000000000000000000007fff") + XCTAssertEqual((UInt256.max >> UInt(242)).hex, "0000000000000000000000000000000000000000000000000000000000003fff") + XCTAssertEqual((UInt256.max >> UInt(243)).hex, "0000000000000000000000000000000000000000000000000000000000001fff") + XCTAssertEqual((UInt256.max >> UInt(244)).hex, "0000000000000000000000000000000000000000000000000000000000000fff") + XCTAssertEqual((UInt256.max >> UInt(245)).hex, "00000000000000000000000000000000000000000000000000000000000007ff") + XCTAssertEqual((UInt256.max >> UInt(246)).hex, "00000000000000000000000000000000000000000000000000000000000003ff") + XCTAssertEqual((UInt256.max >> UInt(247)).hex, "00000000000000000000000000000000000000000000000000000000000001ff") + XCTAssertEqual((UInt256.max >> UInt(248)).hex, "00000000000000000000000000000000000000000000000000000000000000ff") + XCTAssertEqual((UInt256.max >> UInt(249)).hex, "000000000000000000000000000000000000000000000000000000000000007f") + XCTAssertEqual((UInt256.max >> UInt(250)).hex, "000000000000000000000000000000000000000000000000000000000000003f") + XCTAssertEqual((UInt256.max >> UInt(251)).hex, "000000000000000000000000000000000000000000000000000000000000001f") + XCTAssertEqual((UInt256.max >> UInt(252)).hex, "000000000000000000000000000000000000000000000000000000000000000f") + XCTAssertEqual((UInt256.max >> UInt(253)).hex, "0000000000000000000000000000000000000000000000000000000000000007") + XCTAssertEqual((UInt256.max >> UInt(254)).hex, "0000000000000000000000000000000000000000000000000000000000000003") + XCTAssertEqual((UInt256.max >> UInt(255)).hex, "0000000000000000000000000000000000000000000000000000000000000001") + XCTAssertEqual((UInt256.max >> UInt(256)).hex, "0000000000000000000000000000000000000000000000000000000000000000") + } + + func testUInt256Hex1() { + XCTAssertEqual(UInt256(hex: "0102030405060708f1f2f3f4f5f6f7f8e1e2e3e4e5e6e7e8d1d2d3d4d5d6d7d8")!.hex, "0102030405060708f1f2f3f4f5f6f7f8e1e2e3e4e5e6e7e8d1d2d3d4d5d6d7d8") + XCTAssertEqual(UInt256(hex: "0102030405060708f1f2f3f4f5f6f7f8e1e2e3e4e5e6e7e8d1d2d3d4d5d6d7d8")!.data.hex, "d8d7d6d5d4d3d2d1e8e7e6e5e4e3e2e1f8f7f6f5f4f3f2f10807060504030201") + } + + func testUInt256Compare1() { + XCTAssertTrue(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + < UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001")!) + + XCTAssertTrue(UInt256(hex: "00000000_f0000000_f0000000_f0000000_f0000000_f0000000_f0000000_f0000000")! + < UInt256(hex: "00000001_00000000_00000000_00000000_00000000_00000000_00000000_00000000")!) + + XCTAssertTrue(UInt256(hex: "00000000_00d321ae_f0000000_f0000000_f0000000_f0000000_f0000000_f0000000")! + < UInt256(hex: "00000000_00d321af_00000000_00000000_00000000_00000000_00000000_00000000")!) + + XCTAssertTrue(UInt256(hex: "00000000_00000000_0000eefe_f0000000_f0000000_f0000000_f0000000_f0000000")! + < UInt256(hex: "00000000_00000000_0000efed_00000000_00000000_00000000_00000000_00000000")!) + + XCTAssertTrue(UInt256(hex: "00000000_00000000_00000000_01020304_0000000f_0000000f_0000000f_0000000f")! + < UInt256(hex: "00000000_00000000_00000000_0e000000_00000000_00000000_00000000_00000000")!) + + XCTAssertTrue(UInt256(hex: "00000000_00000000_00000000_00000000_d5632433_0000000f_0000000f_0000000f")! + < UInt256(hex: "00000000_00000000_00000000_00000000_f1000000_00000000_00000000_00000000")!) + + XCTAssertTrue(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_21234567_0000000f_0000000f")! + < UInt256(hex: "00000000_00000000_00000000_00000000_00000000_31234567_0000000f_00000000")!) + + XCTAssertTrue(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_1200000f_0000000f")! + < UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_1300000f_00000000")!) + + XCTAssertTrue(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + < UInt256(hex: "10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")!) + + XCTAssertFalse(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + < UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")!) +} + + func testInitFromData() { + XCTAssertNotNil(UInt256(data: Data(count: 32))) + XCTAssertNil(UInt256(data: Data(count: 31))) + XCTAssertNil(UInt256(data: Data(count: 33))) + } + + func testInitFromUInt() { + XCTAssertEqual(UInt256(1 as UInt8).hex, "0000000000000000000000000000000000000000000000000000000000000001") + XCTAssertEqual(UInt256(1 as UInt16).hex, "0000000000000000000000000000000000000000000000000000000000000001") + XCTAssertEqual(UInt256(1 as UInt32).hex, "0000000000000000000000000000000000000000000000000000000000000001") + XCTAssertEqual(UInt256(1 as UInt64).hex, "0000000000000000000000000000000000000000000000000000000000000001") + XCTAssertEqual(UInt256(UInt8.max).hex, "00000000000000000000000000000000000000000000000000000000000000ff") + XCTAssertEqual(UInt256(UInt16.max).hex, "000000000000000000000000000000000000000000000000000000000000ffff") + XCTAssertEqual(UInt256(UInt32.max).hex, "00000000000000000000000000000000000000000000000000000000ffffffff") + XCTAssertEqual(UInt256(UInt64.max).hex, "000000000000000000000000000000000000000000000000ffffffffffffffff") + } + + func testEquatable() { + XCTAssertTrue(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + == UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")!) + XCTAssertTrue(UInt256(hex: "11111111_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + == UInt256(hex: "11111111_00000000_00000000_00000000_00000000_00000000_00000000_00000000")!) + XCTAssertFalse(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + == UInt256(hex: "10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")!) + XCTAssertFalse(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + == UInt256(hex: "00000000_00000000_10000000_00000000_00000000_00000000_00000000_00000000")!) + XCTAssertFalse(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + == UInt256(hex: "00000000_00000000_00000000_00000000_10000000_00000000_00000000_00000000")!) + XCTAssertFalse(UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000")! + == UInt256(hex: "00000000_00000000_00000000_00000000_00000000_00000000_10000000_00000000")!) + } +} diff --git a/Tests/BitcoinKitTests/UInt32MathTests.swift b/Tests/BitcoinKitTests/UInt32MathTests.swift new file mode 100644 index 00000000..df100750 --- /dev/null +++ b/Tests/BitcoinKitTests/UInt32MathTests.swift @@ -0,0 +1,61 @@ +// +// UInt32MathTests.swift +// +// Copyright © 2018 BitcoinKit developers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import XCTest +@testable import BitcoinKit + +class UInt32MathTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func test1() { + XCTAssertEqual(ceil_log2(0), 0) + XCTAssertEqual(ceil_log2(1), 0) + XCTAssertEqual(ceil_log2(2), 1) + XCTAssertEqual(ceil_log2(3), 2) + XCTAssertEqual(ceil_log2(4), 2) + XCTAssertEqual(ceil_log2(5), 3) + XCTAssertEqual(ceil_log2(6), 3) + XCTAssertEqual(ceil_log2(7), 3) + XCTAssertEqual(ceil_log2(8), 3) + XCTAssertEqual(ceil_log2(9), 4) + XCTAssertEqual(ceil_log2(10), 4) + XCTAssertEqual(ceil_log2(11), 4) + XCTAssertEqual(ceil_log2(12), 4) + XCTAssertEqual(ceil_log2(13), 4) + XCTAssertEqual(ceil_log2(14), 4) + XCTAssertEqual(ceil_log2(15), 4) + XCTAssertEqual(ceil_log2(16), 4) + XCTAssertEqual(ceil_log2(17), 5) + + XCTAssertEqual(ceil_log2(UInt32.max-1), 32) + XCTAssertEqual(ceil_log2(UInt32.max), 32) + } +}