From 2f5d4db1b2a85c108b63e6219f779c23291e1600 Mon Sep 17 00:00:00 2001 From: Torkel Rogstad Date: Fri, 23 Aug 2019 18:32:55 +0200 Subject: [PATCH] Bump test coverage (#713) * Bump test coverage * Lower test coverage requirement for chain --- .../bitcoins/rpc/config/BitcoindConfig.scala | 18 ++++-- .../chain/blockchain/ChainHandlerTest.scala | 2 +- chain/{build.sbt => chain.sbt} | 2 +- .../bitcoins/core/crypto/AesCryptTest.scala | 55 +++++++++++++++++- .../bitcoins/core/crypto/ChainCodeTest.scala | 16 ++++++ .../bitcoins/core/crypto/HashDigestTest.scala | 50 +++++++++++++++++ .../core/p2p/GetDataMessageTest.scala | 6 ++ .../core/p2p/GetHeadersMessageTest.scala | 6 ++ .../core/p2p/InventoryMessageTest.scala | 6 ++ .../core/p2p/TransactionMessageTest.scala | 6 ++ .../core/p2p/VersionMessageTest.scala | 6 ++ .../org/bitcoins/core/crypto/AesCrypt.scala | 40 +++---------- .../org/bitcoins/core/crypto/ChainCode.scala | 13 +++-- .../org/bitcoins/core/crypto/HashDigest.scala | 56 ++++++++----------- .../org/bitcoins/core/hd/HDChainType.scala | 2 - .../bitcoins/core/p2p/NetworkPayload.scala | 20 +++---- .../org/bitcoins/core/util/BitcoinSUtil.scala | 14 ----- .../testkit/core/gen/NumberGenerator.scala | 3 + .../org/bitcoins/testkit}/util/FileUtil.scala | 4 +- .../bitcoins/wallet/EncryptedMnemonic.scala | 2 +- .../scala/org/bitcoins/wallet/Wallet.scala | 3 +- .../org/bitcoins/wallet/WalletStorage.scala | 4 +- .../wallet/internal/UtxoHandling.scala | 4 +- 23 files changed, 226 insertions(+), 112 deletions(-) rename chain/{build.sbt => chain.sbt} (58%) create mode 100644 core-test/src/test/scala/org/bitcoins/core/crypto/ChainCodeTest.scala create mode 100644 core-test/src/test/scala/org/bitcoins/core/crypto/HashDigestTest.scala rename {core/src/main/scala/org/bitcoins/core => testkit/src/main/scala/org/bitcoins/testkit}/util/FileUtil.scala (61%) diff --git a/bitcoind-rpc/src/main/scala/org/bitcoins/rpc/config/BitcoindConfig.scala b/bitcoind-rpc/src/main/scala/org/bitcoins/rpc/config/BitcoindConfig.scala index b12961ae67..84ab990cc6 100644 --- a/bitcoind-rpc/src/main/scala/org/bitcoins/rpc/config/BitcoindConfig.scala +++ b/bitcoind-rpc/src/main/scala/org/bitcoins/rpc/config/BitcoindConfig.scala @@ -1,6 +1,6 @@ package org.bitcoins.rpc.config -import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil} +import org.bitcoins.core.util.BitcoinSLogger import org.bitcoins.core.config._ import java.io.File import java.nio.file.Files @@ -207,16 +207,24 @@ case class BitcoindConfig( }.headOption } + import com.sun.jndi.toolkit.url.Uri + + /** Converts a string to an InetSocketAddress */ + private def toInetSocketAddress(string: String): InetSocketAddress = { + val uri = new Uri(string) + new InetSocketAddress(uri.getHost, uri.getPort) + } + lazy val username: Option[String] = getValue("rpcuser") lazy val password: Option[String] = getValue("rpcpassword") lazy val zmqpubrawblock: Option[InetSocketAddress] = - getValue("zmqpubrawblock").map(BitcoinSUtil.toInetSocketAddress) + getValue("zmqpubrawblock").map(toInetSocketAddress) lazy val zmqpubrawtx: Option[InetSocketAddress] = - getValue("zmqpubrawtx").map(BitcoinSUtil.toInetSocketAddress) + getValue("zmqpubrawtx").map(toInetSocketAddress) lazy val zmqpubhashblock: Option[InetSocketAddress] = - getValue("zmqpubhashblock").map(BitcoinSUtil.toInetSocketAddress) + getValue("zmqpubhashblock").map(toInetSocketAddress) lazy val zmqpubhashtx: Option[InetSocketAddress] = - getValue("zmqpubhashtx").map(BitcoinSUtil.toInetSocketAddress) + getValue("zmqpubhashtx").map(toInetSocketAddress) lazy val port: Int = getValue("port").map(_.toInt).getOrElse(network.port) diff --git a/chain-test/src/test/scala/org/bitcoins/chain/blockchain/ChainHandlerTest.scala b/chain-test/src/test/scala/org/bitcoins/chain/blockchain/ChainHandlerTest.scala index e3b5465de4..c7369b7b7f 100644 --- a/chain-test/src/test/scala/org/bitcoins/chain/blockchain/ChainHandlerTest.scala +++ b/chain-test/src/test/scala/org/bitcoins/chain/blockchain/ChainHandlerTest.scala @@ -9,7 +9,7 @@ import org.bitcoins.chain.models.{ BlockHeaderDbHelper } import org.bitcoins.core.protocol.blockchain.BlockHeader -import org.bitcoins.core.util.FileUtil +import org.bitcoins.testkit.util.FileUtil import org.bitcoins.testkit.chain.fixture.ChainFixtureTag import org.bitcoins.testkit.chain.{ BlockHeaderHelper, diff --git a/chain/build.sbt b/chain/chain.sbt similarity index 58% rename from chain/build.sbt rename to chain/chain.sbt index b7a2b423b2..28b0d7e483 100644 --- a/chain/build.sbt +++ b/chain/chain.sbt @@ -1,3 +1,3 @@ -coverageMinimum := 90 +coverageMinimum := 85 coverageFailOnMinimum := true diff --git a/core-test/src/test/scala/org/bitcoins/core/crypto/AesCryptTest.scala b/core-test/src/test/scala/org/bitcoins/core/crypto/AesCryptTest.scala index 4a9f76da70..dd2b013922 100644 --- a/core-test/src/test/scala/org/bitcoins/core/crypto/AesCryptTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/crypto/AesCryptTest.scala @@ -7,6 +7,7 @@ import scodec.bits.{ByteVector, HexStringSyntax} import java.{util => ju} import org.scalatest.compatible.Assertion import org.bitcoins.testkit.core.gen.CryptoGenerators +import org.scalacheck.Gen class AesCryptTest extends BitcoinSUnitTest { behavior of "AesEncrypt" @@ -20,7 +21,7 @@ class AesCryptTest extends BitcoinSUnitTest { val aesKey: AesKey = getKey(hex"12345678123456781234567812345678") - val badAesKey: AesKey = getKey(aesKey.underlying.reverse) + val badAesKey: AesKey = getKey(aesKey.bytes.reverse) /** * The test vectors in this test was generated by using @@ -331,6 +332,25 @@ class AesCryptTest extends BitcoinSUnitTest { assertDoesNotCompile("""val k = new AesKey(hex"1234")""") } + it must "not be constructable from bad byte lenghts" in { + val bytevectorGens: Seq[Gen[ByteVector]] = + (0 until 100) + .filter(!AesKey.keylengths.contains(_)) + .map(NumberGenerator.bytevector(_)) + + val first +: second +: rest = bytevectorGens + val badKeyLenghts: Gen[ByteVector] = + Gen.oneOf(first, second, bytevectorGens: _*) + + forAll(badKeyLenghts) { bytes => + assert(AesKey.fromBytes(bytes).isEmpty) + + intercept[IllegalArgumentException] { + AesKey.fromValidBytes(bytes) + } + } + } + behavior of "AesIV" it must "not have an apply method" in { @@ -342,6 +362,13 @@ class AesCryptTest extends BitcoinSUnitTest { } + it must "not be constructable from invalid length bytes" in { + val bytes = hex"12345" + intercept[IllegalArgumentException] { + AesIV.fromValidBytes(bytes) + } + } + behavior of "AesPassword" it must "not have an apply method" in { @@ -354,5 +381,31 @@ class AesCryptTest extends BitcoinSUnitTest { it must "fail to create an empty AES password" in { assert(AesPassword.fromString("").isEmpty) + intercept[IllegalArgumentException] { + AesPassword.fromNonEmptyString("") + } + } + + it must "be convertable to an AesKey" in { + forAll(CryptoGenerators.aesPassword) { pass => + val (key, salt) = pass.toKey + + assert(key == pass.toKey(salt)) + } + } + + behavior of "AesSalt" + + it must "be able to make random AesSalts with fromBytes/toBytes symmetry" in { + val rand = AesSalt.random + assert(rand == AesSalt.fromBytes(rand.bytes)) + } + + behavior of "AesEncryptedData" + + it must "fail to construct from invalid base64" in { + intercept[IllegalArgumentException] { + AesEncryptedData.fromValidBase64("foobar") + } } } diff --git a/core-test/src/test/scala/org/bitcoins/core/crypto/ChainCodeTest.scala b/core-test/src/test/scala/org/bitcoins/core/crypto/ChainCodeTest.scala new file mode 100644 index 0000000000..d70cb52e17 --- /dev/null +++ b/core-test/src/test/scala/org/bitcoins/core/crypto/ChainCodeTest.scala @@ -0,0 +1,16 @@ +package org.bitcoins.core.crypto + +import org.bitcoins.testkit.util.BitcoinSUnitTest +import org.bitcoins.testkit.core.gen.NumberGenerator + +class ChainCodeTest extends BitcoinSUnitTest { + behavior of "ChainCode" + + it must "not be constructable from invalid lengths byte vectors" in { + forAll(NumberGenerator.bytevector.suchThat(_.length != 32)) { bytes => + intercept[IllegalArgumentException] { + ChainCode.fromBytes(bytes) + } + } + } +} diff --git a/core-test/src/test/scala/org/bitcoins/core/crypto/HashDigestTest.scala b/core-test/src/test/scala/org/bitcoins/core/crypto/HashDigestTest.scala new file mode 100644 index 0000000000..8fb89334f1 --- /dev/null +++ b/core-test/src/test/scala/org/bitcoins/core/crypto/HashDigestTest.scala @@ -0,0 +1,50 @@ +package org.bitcoins.core.crypto + +import org.bitcoins.testkit.util.BitcoinSUnitTest + +import scodec.bits._ +import org.bitcoins.testkit.core.gen.NumberGenerator +import org.bitcoins.testkit.core.gen.CryptoGenerators + +class HashDigestTest extends BitcoinSUnitTest { + behavior of "DoubleSha256Digest" + + it must "be constructable from 32 bytes" in { + forAll(NumberGenerator.bytes(32)) { bytes => + val vec = ByteVector(bytes) + assert(DoubleSha256Digest(vec).bytes == vec) + } + } + + it must "not be constructable from bad byte lenghts" in { + forAll(NumberGenerator.bytevector.suchThat(_.length != 32)) { bytes => + intercept[IllegalArgumentException] { + DoubleSha256Digest(bytes) + } + } + } + + it must "have flip symmetry" in { + forAll(CryptoGenerators.doubleSha256Digest) { hash => + val flipped = hash.flip + assert(flipped.flip == hash) + } + } + + behavior of "DoubleSha256DigestBE" + it must "be constructable from 32 bytes" in { + forAll(NumberGenerator.bytes(32)) { bytes => + val vec = ByteVector(bytes) + assert(DoubleSha256DigestBE(vec).bytes == vec) + } + } + + it must "not be constructable from bad byte lenghts" in { + forAll(NumberGenerator.bytevector.suchThat(_.length != 32)) { bytes => + intercept[IllegalArgumentException] { + DoubleSha256DigestBE(bytes) + } + } + } + +} diff --git a/core-test/src/test/scala/org/bitcoins/core/p2p/GetDataMessageTest.scala b/core-test/src/test/scala/org/bitcoins/core/p2p/GetDataMessageTest.scala index 68eb29f5a5..1d40a1faad 100644 --- a/core-test/src/test/scala/org/bitcoins/core/p2p/GetDataMessageTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/p2p/GetDataMessageTest.scala @@ -23,4 +23,10 @@ class GetDataMessageTest extends BitcoinSUnitTest { val inventory = Inventory(TypeIdentifier.MsgBlock, DoubleSha256Digest.empty) assert(GetDataMessage(inventory) == GetDataMessage(Seq(inventory))) } + + it must "have a meaningful toString" in { + forAll(DataMessageGenerator.getDataMessages) { message => + assert(message.toString.length() < 200) + } + } } diff --git a/core-test/src/test/scala/org/bitcoins/core/p2p/GetHeadersMessageTest.scala b/core-test/src/test/scala/org/bitcoins/core/p2p/GetHeadersMessageTest.scala index a55e9d8bf7..9bdb1d07f1 100644 --- a/core-test/src/test/scala/org/bitcoins/core/p2p/GetHeadersMessageTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/p2p/GetHeadersMessageTest.scala @@ -32,4 +32,10 @@ class GetHeadersMessageTest extends BitcoinSUnitTest { val otherMsg = GetHeadersMessage(hash) assert(otherMsg == GetHeadersMessage(Vector(hash))) } + + it must "have a meaningful toString" in { + forAll(DataMessageGenerator.getHeaderMessages) { message => + assert(message.toString().length() < 300) + } + } } diff --git a/core-test/src/test/scala/org/bitcoins/core/p2p/InventoryMessageTest.scala b/core-test/src/test/scala/org/bitcoins/core/p2p/InventoryMessageTest.scala index 3296150099..2e4c0c7f33 100644 --- a/core-test/src/test/scala/org/bitcoins/core/p2p/InventoryMessageTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/p2p/InventoryMessageTest.scala @@ -10,4 +10,10 @@ class InventoryMessageTest extends BitcoinSUnitTest { assert(InventoryMessage(invMessage.hex) == invMessage) } } + + it must "have a meaningful toString" in { + forAll(DataMessageGenerator.inventoryMessages) { inv => + assert(inv.toString.length < 200) + } + } } diff --git a/core-test/src/test/scala/org/bitcoins/core/p2p/TransactionMessageTest.scala b/core-test/src/test/scala/org/bitcoins/core/p2p/TransactionMessageTest.scala index 9b2504ca3c..5baafc6970 100644 --- a/core-test/src/test/scala/org/bitcoins/core/p2p/TransactionMessageTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/p2p/TransactionMessageTest.scala @@ -11,4 +11,10 @@ class TransactionMessageTest extends BitcoinSUnitTest { } } + it must "have a meaningful toString" in { + forAll(DataMessageGenerator.transactionMessage) { txMsg => + assert(txMsg.toString.length < 120) + } + } + } diff --git a/core-test/src/test/scala/org/bitcoins/core/p2p/VersionMessageTest.scala b/core-test/src/test/scala/org/bitcoins/core/p2p/VersionMessageTest.scala index e440a273ef..6dba55dded 100644 --- a/core-test/src/test/scala/org/bitcoins/core/p2p/VersionMessageTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/p2p/VersionMessageTest.scala @@ -17,6 +17,12 @@ class VersionMessageTest extends BitcoinSUnitTest { } } + it must "have a meaningful toString message" in { + forAll(ControlMessageGenerator.versionMessage) { version => + assert(version.toString.length < 350 + version.userAgent.length()) + } + } + "VersionMessage" must "create a new version message to be sent to another node on the network" in { val versionMessage = VersionMessage(MainNet, InetAddress.getLocalHost) assert(versionMessage.addressReceiveServices.nodeNone) diff --git a/core/src/main/scala/org/bitcoins/core/crypto/AesCrypt.scala b/core/src/main/scala/org/bitcoins/core/crypto/AesCrypt.scala index 4d34f592e0..7837a5d8a3 100644 --- a/core/src/main/scala/org/bitcoins/core/crypto/AesCrypt.scala +++ b/core/src/main/scala/org/bitcoins/core/crypto/AesCrypt.scala @@ -158,23 +158,16 @@ object AesPassword { * [[javax.crypto.SecretKey SecretKey]]s, * and have certain length requirements. */ -final case class AesKey private (private[crypto] val underlying: ByteVector) - extends NetworkElement { - require( - AesKey.keylengths.exists(_ == underlying.length), { - val lengths = AesKey.keylengths.mkString(", ") - s"Invalid AES key length: ${underlying.length}! Valid lengths: $lengths" - } - ) - - override val bytes: ByteVector = underlying +final case class AesKey private (bytes: ByteVector) + extends AnyVal + with NetworkElement { /** * The Java [[javax.crypto.SecretKey SecretKey]] representation * of this key. */ - lazy val toSecretKey: SecretKey = - new SecretKeySpec(underlying.toArray, "AES") + def toSecretKey: SecretKey = + new SecretKeySpec(bytes.toArray, "AES") } @@ -236,15 +229,9 @@ object AesKey { /** Represents an initialization vector (IV) used * in AES encryption. */ -final case class AesIV private (private val underlying: ByteVector) - extends NetworkElement { - require( - underlying.length == 16, - s"AES salt must be 16 bytes long! Got: ${underlying.length}" - ) - - override val bytes: ByteVector = underlying -} +final case class AesIV private (bytes: ByteVector) + extends AnyVal + with NetworkElement object AesIV { @@ -259,7 +246,7 @@ object AesIV { * (in CFB mode, which is what we use here). */ def fromBytes(bytes: ByteVector): Option[AesIV] = - if (bytes.length == AesIV.length) Some(AesIV(bytes)) else None + if (bytes.length == AesIV.length) Some(new AesIV(bytes)) else None /** Constructs an AES IV from the given bytes. Throws if the given bytes are invalid */ def fromValidBytes(bytes: ByteVector): AesIV = @@ -347,15 +334,6 @@ object AesCrypt { iv: AesIV, key: AesKey): AesEncryptedData = { val cipher = encryptionCipher(key, iv) - val params = cipher.getParameters - - // if assertions aren't enabled, this calculation won't - // get triggered - lazy val foundIV = params.getParameterSpec(classOf[IvParameterSpec]).getIV - assert( - ByteVector(foundIV) == iv.bytes, - s"foundIV: ${ByteVector(foundIV).toHex}, iv: ${iv.hex}" - ) val cipherText = cipher.doFinal(plainText.toArray) diff --git a/core/src/main/scala/org/bitcoins/core/crypto/ChainCode.scala b/core/src/main/scala/org/bitcoins/core/crypto/ChainCode.scala index 9f93bbaa60..16b5a84681 100644 --- a/core/src/main/scala/org/bitcoins/core/crypto/ChainCode.scala +++ b/core/src/main/scala/org/bitcoins/core/crypto/ChainCode.scala @@ -4,13 +4,14 @@ import org.bitcoins.core.protocol.NetworkElement import org.bitcoins.core.util.Factory import scodec.bits.ByteVector -sealed abstract class ChainCode extends NetworkElement +case class ChainCode(bytes: ByteVector) extends NetworkElement { + require(bytes.size == 32, + "ChainCode must be 32 bytes in size, got: " + bytes.size) +} object ChainCode extends Factory[ChainCode] { - private case class ChainCodeImpl(bytes: ByteVector) extends ChainCode { - require(bytes.size == 32, - "ChainCode must be 32 bytes in size, got: " + bytes.size) - } - def fromBytes(bytes: ByteVector): ChainCode = ChainCodeImpl(bytes) + def fromBytes(bytes: ByteVector): ChainCode = + // use new to avoid inf loop + new ChainCode(bytes) } diff --git a/core/src/main/scala/org/bitcoins/core/crypto/HashDigest.scala b/core/src/main/scala/org/bitcoins/core/crypto/HashDigest.scala index 3c1cbcf30a..799c0dc93a 100644 --- a/core/src/main/scala/org/bitcoins/core/crypto/HashDigest.scala +++ b/core/src/main/scala/org/bitcoins/core/crypto/HashDigest.scala @@ -4,9 +4,6 @@ import org.bitcoins.core.protocol.NetworkElement import org.bitcoins.core.util.Factory import scodec.bits.ByteVector -/** - * Created by chris on 5/24/16. - */ sealed trait HashDigest extends Any with NetworkElement { /** The message digest represented in bytes */ @@ -109,49 +106,44 @@ object Sha256DigestBE extends Factory[Sha256DigestBE] { /** * Represents the result of SHA256(SHA256()) */ -sealed trait DoubleSha256Digest extends Any with HashDigest { - def flip: DoubleSha256DigestBE = DoubleSha256DigestBE(bytes.reverse) +case class DoubleSha256Digest(bytes: ByteVector) extends HashDigest { + require(bytes.length == 32, + "DoubleSha256Digest must always be 32 bytes, got: " + bytes.length) + + lazy val flip: DoubleSha256DigestBE = DoubleSha256DigestBE(bytes.reverse) + + override def toString = s"DoubleSha256Digest($hex)" } object DoubleSha256Digest extends Factory[DoubleSha256Digest] { - private case class DoubleSha256DigestImpl(bytes: ByteVector) - extends AnyVal - with DoubleSha256Digest { - override def toString = s"DoubleSha256DigestImpl($hex)" - // $COVERAGE-ON$ - } override def fromBytes(bytes: ByteVector): DoubleSha256Digest = { - require(bytes.length == 32, - // $COVERAGE-OFF$ - "DoubleSha256Digest must always be 32 bytes, got: " + bytes.length) - DoubleSha256DigestImpl(bytes) + // have to use new to avoid infinite loop + new DoubleSha256Digest(bytes) } - private val e = ByteVector(Array.fill(32)(0.toByte)) - val empty: DoubleSha256Digest = DoubleSha256Digest.fromBytes(e) + val empty: DoubleSha256Digest = DoubleSha256Digest( + ByteVector.low(32) + ) } /** The big endian version of [[org.bitcoins.core.crypto.DoubleSha256Digest DoubleSha256Digest]] */ -sealed trait DoubleSha256DigestBE extends Any with HashDigest { - def flip: DoubleSha256Digest = DoubleSha256Digest.fromBytes(bytes.reverse) +case class DoubleSha256DigestBE(bytes: ByteVector) extends HashDigest { + require(bytes.length == 32, + "DoubleSha256Digest must always be 32 bytes, got: " + bytes.length) + + def flip: DoubleSha256Digest = + DoubleSha256Digest.fromBytes(bytes.reverse) + + override def toString = s"DoubleSha256BDigestBE($hex)" } object DoubleSha256DigestBE extends Factory[DoubleSha256DigestBE] { - private case class DoubleSha256DigestBEImpl(bytes: ByteVector) - extends AnyVal - with DoubleSha256DigestBE { - override def toString = s"DoubleSha256BDigestBEImpl($hex)" - // $COVERAGE-ON$ - } - override def fromBytes(bytes: ByteVector): DoubleSha256DigestBE = { - require(bytes.length == 32, - // $COVERAGE-OFF$ - "DoubleSha256Digest must always be 32 bytes, got: " + bytes.length) - DoubleSha256DigestBEImpl(bytes) - } + override def fromBytes(bytes: ByteVector): DoubleSha256DigestBE = + // have to use new to avoid infinite loop + new DoubleSha256DigestBE(bytes) - val empty: DoubleSha256DigestBE = DoubleSha256Digest.empty.flip + val empty: DoubleSha256DigestBE = DoubleSha256DigestBE(ByteVector.low(32)) } /** diff --git a/core/src/main/scala/org/bitcoins/core/hd/HDChainType.scala b/core/src/main/scala/org/bitcoins/core/hd/HDChainType.scala index 114a03c080..c553338dfb 100644 --- a/core/src/main/scala/org/bitcoins/core/hd/HDChainType.scala +++ b/core/src/main/scala/org/bitcoins/core/hd/HDChainType.scala @@ -10,8 +10,6 @@ package org.bitcoins.core.hd * @see */ sealed abstract class HDChainType { - require(index >= 0, s"HDChainType index must be positive, got: $index") - def index: Int } diff --git a/core/src/main/scala/org/bitcoins/core/p2p/NetworkPayload.scala b/core/src/main/scala/org/bitcoins/core/p2p/NetworkPayload.scala index 938afcd4e7..d2b2356694 100644 --- a/core/src/main/scala/org/bitcoins/core/p2p/NetworkPayload.scala +++ b/core/src/main/scala/org/bitcoins/core/p2p/NetworkPayload.scala @@ -200,10 +200,10 @@ trait GetHeadersMessage extends DataPayload { override def toString(): String = { val count = hashCount.toInt - val hashesStr = if (count > 5) { - hashes.take(5).mkString + "..." - } else { - hashes.mkString + // only display first hash, otherwise this gets really long + val hashesStr = hashes match { + case head +: Nil => head.toString + case head +: _ => s"$head, ..." } s"GetHeadersMessage($version, hashCount=$count, hashes=$hashesStr, stop=$hashStop)" } @@ -326,12 +326,12 @@ trait InventoryMessage extends DataPayload { override def toString(): String = { val invCount = inventoryCount.toInt - val limit = 5 - val invList = if (invCount > limit) { - inventories.take(limit).mkString + "..." - } else { - inventories.mkString - } + val invList = + if (invCount > 1) { + inventories.take(1).mkString + "..." + } else { + inventories.mkString + } s"InventoryMessage($invCount inv(s)${if (invList.nonEmpty) ", " + invList else ""})" } diff --git a/core/src/main/scala/org/bitcoins/core/util/BitcoinSUtil.scala b/core/src/main/scala/org/bitcoins/core/util/BitcoinSUtil.scala index dcf4221535..a659b62cce 100644 --- a/core/src/main/scala/org/bitcoins/core/util/BitcoinSUtil.scala +++ b/core/src/main/scala/org/bitcoins/core/util/BitcoinSUtil.scala @@ -1,8 +1,5 @@ package org.bitcoins.core.util -import java.net.InetSocketAddress - -import com.sun.jndi.toolkit.url.Uri import org.bitcoins.core.protocol.NetworkElement import scodec.bits.{BitVector, ByteVector} @@ -67,8 +64,6 @@ trait BitcoinSUtil { /** Flips the endianness of the given sequence of bytes. */ def flipEndianness(bytes: ByteVector): String = encodeHex(bytes.reverse) - def flipEndiannessBytes(bytes: ByteVector): ByteVector = bytes.reverse - /** * Adds the amount padding bytes needed to fix the size of the hex string * for instance, ints are required to be 4 bytes. If the number is just 1 @@ -82,11 +77,6 @@ trait BitcoinSUtil { paddedHex } - /** Converts a sequence of bytes to a sequence of bit vectors */ - def bytesToBitVectors(bytes: ByteVector): BitVector = { - bytes.toBitVector - } - /** Converts a byte to a bit vector representing that byte */ def byteToBitVector(byte: Byte): BitVector = { BitVector.fromByte(byte) @@ -104,10 +94,6 @@ trait BitcoinSUtil { h.foldLeft(ByteVector.empty)(_ ++ _.bytes) } - def toInetSocketAddress(string: String): InetSocketAddress = { - val uri = new Uri(string) - new InetSocketAddress(uri.getHost, uri.getPort) - } } object BitcoinSUtil extends BitcoinSUtil diff --git a/testkit/src/main/scala/org/bitcoins/testkit/core/gen/NumberGenerator.scala b/testkit/src/main/scala/org/bitcoins/testkit/core/gen/NumberGenerator.scala index 589d7fb260..98b2de0ea9 100644 --- a/testkit/src/main/scala/org/bitcoins/testkit/core/gen/NumberGenerator.scala +++ b/testkit/src/main/scala/org/bitcoins/testkit/core/gen/NumberGenerator.scala @@ -98,6 +98,9 @@ trait NumberGenerator { /** Generates an arbitrary [[scodec.bits.ByteVector ByteVector]] */ def bytevector: Gen[ByteVector] = Gen.listOf(byte).map(ByteVector(_)) + def bytevector(length: Int): Gen[ByteVector] = + Gen.listOfN(length, byte).map(ByteVector(_)) + /** Generates a 100 byte sequence */ def bytes: Gen[List[Byte]] = for { diff --git a/core/src/main/scala/org/bitcoins/core/util/FileUtil.scala b/testkit/src/main/scala/org/bitcoins/testkit/util/FileUtil.scala similarity index 61% rename from core/src/main/scala/org/bitcoins/core/util/FileUtil.scala rename to testkit/src/main/scala/org/bitcoins/testkit/util/FileUtil.scala index 0385190a9e..f3c0ec6d7a 100644 --- a/core/src/main/scala/org/bitcoins/core/util/FileUtil.scala +++ b/testkit/src/main/scala/org/bitcoins/testkit/util/FileUtil.scala @@ -1,8 +1,8 @@ -package org.bitcoins.core.util +package org.bitcoins.testkit.util object FileUtil { - /** Returns a BufferedSource for any file on the classpath */ + /** Returns a `BufferedSource` for any file on the classpath */ def getFileAsSource(fileName: String): scala.io.BufferedSource = { scala.io.Source.fromURL(getClass.getResource(s"/$fileName")) } diff --git a/wallet/src/main/scala/org/bitcoins/wallet/EncryptedMnemonic.scala b/wallet/src/main/scala/org/bitcoins/wallet/EncryptedMnemonic.scala index a131ec8627..212d3cf3aa 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/EncryptedMnemonic.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/EncryptedMnemonic.scala @@ -8,7 +8,7 @@ import scala.util.{Failure, Success, Try} case class EncryptedMnemonic(value: AesEncryptedData, salt: AesSalt) { def toMnemonic(password: AesPassword): Try[MnemonicCode] = { - import org.bitcoins.core.util.EitherUtil.EitherOps._ + import EitherUtil.EitherOps._ val key = password.toKey(salt) AesCrypt.decrypt(value, key).toTry.flatMap { decrypted => decrypted.decodeUtf8 match { diff --git a/wallet/src/main/scala/org/bitcoins/wallet/Wallet.scala b/wallet/src/main/scala/org/bitcoins/wallet/Wallet.scala index 2dc729e105..82605cce17 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/Wallet.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/Wallet.scala @@ -6,7 +6,6 @@ import org.bitcoins.core.currency._ import org.bitcoins.core.hd._ import org.bitcoins.core.protocol.BitcoinAddress import org.bitcoins.core.protocol.transaction._ -import org.bitcoins.core.util.EitherUtil import org.bitcoins.core.wallet.builder.BitcoinTxBuilder import org.bitcoins.core.wallet.fee.FeeUnit import org.bitcoins.core.wallet.utxo.BitcoinUTXOSpendingInfo @@ -162,7 +161,7 @@ object Wallet extends CreateWalletApi with KeyHandlingLogger { override def initializeWithEntropy(entropy: BitVector)( implicit config: WalletAppConfig, ec: ExecutionContext): Future[InitializeWalletResult] = { - import org.bitcoins.core.util.EitherUtil.EitherOps._ + import EitherUtil.EitherOps._ logger.info(s"Initializing wallet on chain ${config.network}") diff --git a/wallet/src/main/scala/org/bitcoins/wallet/WalletStorage.scala b/wallet/src/main/scala/org/bitcoins/wallet/WalletStorage.scala index b3a9292da2..8b828cd427 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/WalletStorage.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/WalletStorage.scala @@ -134,7 +134,7 @@ object WalletStorage extends KeyHandlingLogger { } } - import org.bitcoins.core.util.EitherUtil.EitherOps._ + import EitherUtil.EitherOps._ import MnemonicJsonKeys._ import ReadMnemonicError._ @@ -185,7 +185,7 @@ object WalletStorage extends KeyHandlingLogger { val encryptedEither = readEncryptedMnemonicFromDisk() - import org.bitcoins.core.util.EitherUtil.EitherOps._ + import EitherUtil.EitherOps._ val decryptedEither: Either[ReadMnemonicError, MnemonicCode] = encryptedEither.flatMap { encrypted => encrypted.toMnemonic(passphrase) match { diff --git a/wallet/src/main/scala/org/bitcoins/wallet/internal/UtxoHandling.scala b/wallet/src/main/scala/org/bitcoins/wallet/internal/UtxoHandling.scala index afdef869d5..5f6c02fd98 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/internal/UtxoHandling.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/internal/UtxoHandling.scala @@ -15,7 +15,7 @@ import org.bitcoins.core.protocol.transaction.Transaction import org.bitcoins.wallet.api.AddUtxoResult import org.bitcoins.core.number.UInt32 import org.bitcoins.wallet.api.AddUtxoError -import org.bitcoins.core.util.EitherUtil +import org.bitcoins.wallet.EitherUtil import org.bitcoins.wallet.api.AddUtxoSuccess import org.bitcoins.core.protocol.script.ScriptPubKey import org.bitcoins.core.protocol.BitcoinAddress @@ -103,7 +103,7 @@ private[wallet] trait UtxoHandling extends KeyHandlingLogger { confirmations: Int, spent: Boolean): Future[AddUtxoResult] = { import AddUtxoError._ - import org.bitcoins.core.util.EitherUtil.EitherOps._ + import EitherUtil.EitherOps._ logger.info(s"Adding UTXO to wallet: ${transaction.txId.hex}:${vout.toInt}")