Run test:scalafmt, and enforce it on CI (#1023)

* Run test:scalafmt, and enforce it on CI

* Run test:scalafmt
This commit is contained in:
Chris Stewart 2020-01-23 14:46:57 -06:00 committed by GitHub
parent c968e79c80
commit 754aa77617
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 490 additions and 311 deletions

View file

@ -64,7 +64,7 @@ matrix:
name: Compile website and check formatting
script:
- sbt docs/mdoc
- sbt scalafmtCheck
- sbt test:scalafmtCheck
# Release snapshots/versions of all libraries
# run ci-release only if previous stages passed

View file

@ -5,7 +5,10 @@ import java.io.File
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.script.ScriptSignature
import org.bitcoins.core.protocol.transaction.{TransactionInput, TransactionOutPoint}
import org.bitcoins.core.protocol.transaction.{
TransactionInput,
TransactionOutPoint
}
import org.bitcoins.rpc.client.common.BitcoindRpcClient
import org.bitcoins.rpc.client.common.BitcoindVersion.V18
import org.bitcoins.rpc.config.BitcoindInstance

View file

@ -17,7 +17,8 @@ class ChainAppConfigTest extends ChainUnitTest {
//if we don't turn off logging here, isInitF a few lines down will
//produce some nasty error logs since we are testing initialization
//of the chain project
val chainAppConfig = appConfig.withOverrides(ConfigFactory.parseString("bitcoin-s.logging.level=OFF"))
val chainAppConfig = appConfig.withOverrides(
ConfigFactory.parseString("bitcoin-s.logging.level=OFF"))
behavior of "ChainAppConfig"

View file

@ -96,7 +96,7 @@ class ECPrivateKeyTest extends BitcoinSUnitTest {
}
it must "not serialize a ECPrivateKey toString" in {
ECPrivateKey().toString must be ("Masked(ECPrivateKeyImpl)")
ECPrivateKey().toString must be("Masked(ECPrivateKeyImpl)")
}
}

View file

@ -17,15 +17,15 @@ class ExtKeySpec extends BitcoinSUnitTest {
it must "have serialization symmetry" in {
Prop.forAll(CryptoGenerators.extKey) { extKey =>
ExtKey.fromString(extKey.toString) == Success(extKey) &&
ExtKey(extKey.bytes) == extKey
ExtKey(extKey.bytes) == extKey
}
}
it must "have derivation identity 1" in {
Prop.forAllNoShrink(CryptoGenerators.extPrivateKey,
nonHardened,
nonHardened,
nonHardened) { (m, a, b, c) =>
nonHardened,
nonHardened,
nonHardened) { (m, a, b, c) =>
//https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#the-key-tree
//N(m/a/b/c) = N(m/a/b)/c = N(m/a)/b/c = N(m)/a/b/c = M/a/b/c
val path1 = m
@ -59,9 +59,9 @@ class ExtKeySpec extends BitcoinSUnitTest {
it must "derivation identity 2" in {
Prop.forAllNoShrink(CryptoGenerators.extPrivateKey,
hardened,
nonHardened,
nonHardened) { (m, aH, b, c) =>
hardened,
nonHardened,
nonHardened) { (m, aH, b, c) =>
//https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#the-key-tree
//N(m/aH/b/c) = N(m/aH/b)/c = N(m/aH)/b/c
val path1 = m

View file

@ -246,8 +246,8 @@ class ExtKeyTest extends BitcoinSUnitTest {
val seedBytes =
hex"4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be"
val masterPriv = ExtPrivateKey(LegacyMainNetPriv,
Some(seedBytes), BIP32Path.empty)
masterPriv.toString must be (s"Masked(ExtPrivateKeyImpl)")
val masterPriv =
ExtPrivateKey(LegacyMainNetPriv, Some(seedBytes), BIP32Path.empty)
masterPriv.toString must be(s"Masked(ExtPrivateKeyImpl)")
}
}

View file

@ -9,17 +9,19 @@ class ExtSignTest extends BitcoinSAsyncTest {
forAll(CryptoGenerators.extPrivateKey, CryptoGenerators.sha256Digest) {
case (extPrivKey, hash) =>
val sig = extPrivKey.sign(hash.bytes)
assert(extPrivKey.publicKey.verify(hash,sig))
assert(extPrivKey.publicKey.verify(hash, sig))
}
}
it must "be able to sign a specific path of a ext key" in {
forAllAsync(CryptoGenerators.extPrivateKey, CryptoGenerators.sha256Digest, HDGenerators.bip32Path) {
forAllAsync(CryptoGenerators.extPrivateKey,
CryptoGenerators.sha256Digest,
HDGenerators.bip32Path) {
case (extPrivKey, hash, path) =>
val sigF = extPrivKey.deriveAndSignFuture(hash.bytes,path)
val sigF = extPrivKey.deriveAndSignFuture(hash.bytes, path)
val childPubKey = extPrivKey.deriveChildPubKey(path).get
sigF.map { sig =>
assert(childPubKey.key.verify(hash,sig))
assert(childPubKey.key.verify(hash, sig))
}
}

View file

@ -257,25 +257,25 @@ class MnemonicCodeTest extends BitcoinSUnitTest {
it must "not serialize a MnemonicCode toString" in {
val correctSeed = Vector("phone",
"dilemma",
"early",
"never",
"test",
"surge",
"ecology",
"rail",
"medal",
"benefit",
"mystery",
"toward",
"lounge",
"candy",
"syrup")
"dilemma",
"early",
"never",
"test",
"surge",
"ecology",
"rail",
"medal",
"benefit",
"mystery",
"toward",
"lounge",
"candy",
"syrup")
val mnemonicCode = MnemonicCode.fromWords(correctSeed)
mnemonicCode.toString must be ("Masked(MnemonicCodeImpl)")
mnemonicCode.toString must be("Masked(MnemonicCodeImpl)")
mnemonicCode.toStringSensitive must be (correctSeed.mkString(","))
mnemonicCode.toStringSensitive must be(correctSeed.mkString(","))
}
}

View file

@ -15,6 +15,7 @@ class FilterTypeTest extends BitcoinSUnitTest {
assert(FilterType.getCode(FilterType.Basic) == 0)
assert(FilterType.byCode(0) == FilterType.Basic)
assertThrows[IllegalArgumentException](FilterType.byCode(1))
assertThrows[IllegalArgumentException](FilterType.getCode(FilterType.fromHex("ffff")))
assertThrows[IllegalArgumentException](
FilterType.getCode(FilterType.fromHex("ffff")))
}
}

View file

@ -8,7 +8,7 @@ class HDAccountTest extends BitcoinSUnitTest {
behavior of "HDAccount"
override implicit val generatorDrivenConfig: PropertyCheckConfiguration = {
implicit override val generatorDrivenConfig: PropertyCheckConfiguration = {
generatorDrivenConfigNewCode
}
@ -24,7 +24,9 @@ class HDAccountTest extends BitcoinSUnitTest {
val isNotSame = !HDAccount.isSameAccount(missingLast, defaultAcct)
assert(isNotSame, s"If we drop the last element from the defualt path, we are not in the same account anymore")
assert(
isNotSame,
s"If we drop the last element from the defualt path, we are not in the same account anymore")
}
it must "fail if we modify the last element in the path" in {
@ -33,7 +35,8 @@ class HDAccountTest extends BitcoinSUnitTest {
val isNotSame = !HDAccount.isSameAccount(modifiedLast, defaultAcct)
assert(isNotSame, s"We should have the same account if we modify the account index")
assert(isNotSame,
s"We should have the same account if we modify the account index")
}
it must "succeed if we add an arbitrary element onto the end of the path" in {
@ -41,7 +44,9 @@ class HDAccountTest extends BitcoinSUnitTest {
val isSame = HDAccount.isSameAccount(extraNode, defaultAcct)
assert(isSame, s"If we add an extra element onto the path, we are still in the same account")
assert(
isSame,
s"If we add an extra element onto the path, we are still in the same account")
}
it must "fail with the empty path" in {
@ -58,8 +63,9 @@ class HDAccountTest extends BitcoinSUnitTest {
}
it must "not taken an arbitrary path and arbitrary account and find them in the same account" in {
forAll(HDGenerators.hdAccount, HDGenerators.bip32Path) { case (acct, path) =>
assert(!HDAccount.isSameAccount(path, acct))
forAll(HDGenerators.hdAccount, HDGenerators.bip32Path) {
case (acct, path) =>
assert(!HDAccount.isSameAccount(path, acct))
}
}
}

View file

@ -39,13 +39,22 @@ class ServiceIdentifierTest extends BitcoinSUnitTest {
}
it must "correctly get a ServiceIdentifier from string" in {
assert(ServiceIdentifier.fromString("NETWORK") == ServiceIdentifier.NODE_NETWORK)
assert(ServiceIdentifier.fromString("NETWORK_LIMITED") == ServiceIdentifier.NODE_NETWORK_LIMITED)
assert(ServiceIdentifier.fromString("WITNESS") == ServiceIdentifier.NODE_WITNESS)
assert(ServiceIdentifier.fromString("BLOOM") == ServiceIdentifier.NODE_BLOOM)
assert(ServiceIdentifier.fromString("GETUTXO") == ServiceIdentifier.NODE_GET_UTXO)
assert(ServiceIdentifier.fromString("COMPACT_FILTERS") == ServiceIdentifier.NODE_COMPACT_FILTERS)
assert(ServiceIdentifier.fromString("XTHIN") == ServiceIdentifier.NODE_XTHIN)
assertThrows[IllegalArgumentException](ServiceIdentifier.fromString("this is invalid"))
assert(
ServiceIdentifier.fromString("NETWORK") == ServiceIdentifier.NODE_NETWORK)
assert(ServiceIdentifier
.fromString("NETWORK_LIMITED") == ServiceIdentifier.NODE_NETWORK_LIMITED)
assert(
ServiceIdentifier.fromString("WITNESS") == ServiceIdentifier.NODE_WITNESS)
assert(
ServiceIdentifier.fromString("BLOOM") == ServiceIdentifier.NODE_BLOOM)
assert(
ServiceIdentifier
.fromString("GETUTXO") == ServiceIdentifier.NODE_GET_UTXO)
assert(ServiceIdentifier
.fromString("COMPACT_FILTERS") == ServiceIdentifier.NODE_COMPACT_FILTERS)
assert(
ServiceIdentifier.fromString("XTHIN") == ServiceIdentifier.NODE_XTHIN)
assertThrows[IllegalArgumentException](
ServiceIdentifier.fromString("this is invalid"))
}
}

View file

@ -2,7 +2,14 @@ package org.bitcoins.core.protocol
import org.bitcoins.core.config.{MainNet, RegTest, TestNet3}
import org.bitcoins.core.crypto.{ECPublicKey, Sha256Hash160Digest}
import org.bitcoins.core.protocol.script.{EmptyScriptPubKey, P2PKHScriptPubKey, P2SHScriptPubKey, P2WPKHWitnessSPKV0, ScriptPubKey, WitnessScriptPubKeyV0}
import org.bitcoins.core.protocol.script.{
EmptyScriptPubKey,
P2PKHScriptPubKey,
P2SHScriptPubKey,
P2WPKHWitnessSPKV0,
ScriptPubKey,
WitnessScriptPubKeyV0
}
import org.bitcoins.testkit.util.BitcoinSUnitTest
import scala.util.{Failure, Success, Try}

View file

@ -2,7 +2,12 @@ package org.bitcoins.core.protocol.script
import org.bitcoins.core.crypto.ECPrivateKey
import org.bitcoins.core.script.bitwise.OP_EQUALVERIFY
import org.bitcoins.core.script.constant.{BytesToPushOntoStack, ScriptConstant, ScriptNumber, ScriptToken}
import org.bitcoins.core.script.constant.{
BytesToPushOntoStack,
ScriptConstant,
ScriptNumber,
ScriptToken
}
import org.bitcoins.core.script.crypto.{OP_CHECKSIG, OP_HASH160}
import org.bitcoins.core.script.locktime.OP_CHECKLOCKTIMEVERIFY
import org.bitcoins.core.script.stack.{OP_DROP, OP_DUP}

View file

@ -2,7 +2,12 @@ package org.bitcoins.core.protocol.script
import org.bitcoins.core.crypto.ECPrivateKey
import org.bitcoins.core.script.bitwise.OP_EQUALVERIFY
import org.bitcoins.core.script.constant.{BytesToPushOntoStack, ScriptConstant, ScriptNumber, ScriptToken}
import org.bitcoins.core.script.constant.{
BytesToPushOntoStack,
ScriptConstant,
ScriptNumber,
ScriptToken
}
import org.bitcoins.core.script.crypto.{OP_CHECKSIG, OP_HASH160}
import org.bitcoins.core.script.locktime.OP_CHECKSEQUENCEVERIFY
import org.bitcoins.core.script.stack.{OP_DROP, OP_DUP}

View file

@ -1,7 +1,11 @@
package org.bitcoins.core.protocol.script
import org.bitcoins.core.crypto.ECPublicKey
import org.bitcoins.core.script.constant.{BytesToPushOntoStack, OP_0, ScriptConstant}
import org.bitcoins.core.script.constant.{
BytesToPushOntoStack,
OP_0,
ScriptConstant
}
import org.bitcoins.core.util.BitcoinSLogger
import org.bitcoins.testkit.util.TestUtil
import org.scalatest.{FlatSpec, MustMatchers}

View file

@ -5,7 +5,12 @@ import org.bitcoins.core.currency.CurrencyUnits
import org.bitcoins.core.number.Int32
import org.bitcoins.core.policy.Policy
import org.bitcoins.core.protocol.script.testprotocol.SignatureHashTestCase
import org.bitcoins.core.protocol.transaction.{BaseTransaction, Transaction, TransactionOutput, WitnessTransaction}
import org.bitcoins.core.protocol.transaction.{
BaseTransaction,
Transaction,
TransactionOutput,
WitnessTransaction
}
import org.bitcoins.core.script.crypto.{HashType, SIGHASH_ALL}
import org.bitcoins.core.serializers.script.RawScriptSignatureParser
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil}

View file

@ -1,6 +1,9 @@
package org.bitcoins.core.protocol.transaction
import org.bitcoins.core.protocol.script.{EmptyScriptSignature, P2PKScriptSignature}
import org.bitcoins.core.protocol.script.{
EmptyScriptSignature,
P2PKScriptSignature
}
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
/**

View file

@ -1,6 +1,10 @@
package org.bitcoins.core.protocol.transaction
import org.bitcoins.core.crypto.{BaseTxSigComponent, WitnessTxSigComponentP2SH, WitnessTxSigComponentRaw}
import org.bitcoins.core.crypto.{
BaseTxSigComponent,
WitnessTxSigComponentP2SH,
WitnessTxSigComponentRaw
}
import org.bitcoins.core.currency.CurrencyUnits
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.script._

View file

@ -3,7 +3,10 @@ package org.bitcoins.core.script.arithmetic
import org.bitcoins.core.script.constant._
import org.bitcoins.core.script.flag.ScriptFlag
import org.bitcoins.core.script.result._
import org.bitcoins.core.script.{ExecutedScriptProgram, ExecutionInProgressScriptProgram}
import org.bitcoins.core.script.{
ExecutedScriptProgram,
ExecutionInProgressScriptProgram
}
import org.bitcoins.core.util.ScriptProgramTestUtil
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}

View file

@ -3,7 +3,10 @@ package org.bitcoins.core.script.constant
import org.bitcoins.core.script.bitwise.OP_EQUAL
import org.bitcoins.core.script.crypto.OP_CHECKMULTISIGVERIFY
import org.bitcoins.core.script.flag.{ScriptFlag, ScriptVerifyMinimalData}
import org.bitcoins.core.script.result.{ScriptErrorBadOpCode, ScriptErrorMinimalData}
import org.bitcoins.core.script.result.{
ScriptErrorBadOpCode,
ScriptErrorMinimalData
}
import org.bitcoins.core.util.ScriptProgramTestUtil
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
import scodec.bits.ByteVector

View file

@ -1,11 +1,18 @@
package org.bitcoins.core.script.control
import org.bitcoins.core.script.{ExecutedScriptProgram, ExecutionInProgressScriptProgram, StartedScriptProgram}
import org.bitcoins.core.script.{
ExecutedScriptProgram,
ExecutionInProgressScriptProgram,
StartedScriptProgram
}
import org.bitcoins.core.script.arithmetic.OP_ADD
import org.bitcoins.core.script.bitwise.OP_EQUAL
import org.bitcoins.core.script.constant._
import org.bitcoins.core.script.reserved.{OP_RESERVED, OP_VER}
import org.bitcoins.core.script.result.{ScriptErrorInvalidStackOperation, ScriptErrorOpReturn}
import org.bitcoins.core.script.result.{
ScriptErrorInvalidStackOperation,
ScriptErrorOpReturn
}
import org.bitcoins.core.serializers.script.ScriptParser
import org.bitcoins.core.util._
import org.bitcoins.testkit.util.TestUtil

View file

@ -7,7 +7,11 @@ import org.bitcoins.core.protocol.script.ScriptSignature
import org.bitcoins.core.protocol.transaction._
import org.bitcoins.core.script._
import org.bitcoins.core.script.constant._
import org.bitcoins.core.script.flag.{ScriptFlagFactory, ScriptVerifyDerSig, ScriptVerifyNullDummy}
import org.bitcoins.core.script.flag.{
ScriptFlagFactory,
ScriptVerifyDerSig,
ScriptVerifyNullDummy
}
import org.bitcoins.core.script.result._
import org.bitcoins.core.util.{BitcoinSLogger, ScriptProgramTestUtil}
import org.bitcoins.testkit.util.TestUtil

View file

@ -1,9 +1,16 @@
package org.bitcoins.core.script.interpreter
import org.bitcoins.core.crypto.{BaseTxSigComponent, WitnessTxSigComponentP2SH, WitnessTxSigComponentRaw}
import org.bitcoins.core.crypto.{
BaseTxSigComponent,
WitnessTxSigComponentP2SH,
WitnessTxSigComponentRaw
}
import org.bitcoins.core.currency.CurrencyUnits
import org.bitcoins.core.protocol.script._
import org.bitcoins.core.protocol.transaction.{TransactionOutput, WitnessTransaction}
import org.bitcoins.core.protocol.transaction.{
TransactionOutput,
WitnessTransaction
}
import org.bitcoins.core.script.PreExecutionScriptProgram
import org.bitcoins.core.script.flag.ScriptFlagFactory
import org.bitcoins.core.script.interpreter.testprotocol.CoreTestCase

View file

@ -6,7 +6,10 @@ import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.transaction._
import org.bitcoins.core.script.constant.{OP_0, ScriptNumber}
import org.bitcoins.core.script.result._
import org.bitcoins.core.script.{ExecutedScriptProgram, PreExecutionScriptProgram}
import org.bitcoins.core.script.{
ExecutedScriptProgram,
PreExecutionScriptProgram
}
import org.bitcoins.core.util.ScriptProgramTestUtil
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}

View file

@ -22,7 +22,8 @@ class RawScriptSignatureParserTest extends BitcoinSUnitTest {
}
it must "read an EmptyScriptSignature" in {
assert(RawScriptSignatureParser.read(ByteVector.empty) == EmptyScriptSignature)
assert(
RawScriptSignatureParser.read(ByteVector.empty) == EmptyScriptSignature)
}
it must "read then write a raw script sig" in {

View file

@ -4,7 +4,11 @@ import org.bitcoins.core.script.arithmetic.OP_1ADD
import org.bitcoins.core.script.bitwise.{OP_EQUAL, OP_EQUALVERIFY}
import org.bitcoins.core.script.constant._
import org.bitcoins.core.script.control.{OP_ELSE, OP_ENDIF, OP_IF, OP_NOTIF}
import org.bitcoins.core.script.crypto.{OP_CHECKMULTISIG, OP_CHECKSIG, OP_HASH160}
import org.bitcoins.core.script.crypto.{
OP_CHECKMULTISIG,
OP_CHECKSIG,
OP_HASH160
}
import org.bitcoins.core.script.locktime.OP_CHECKLOCKTIMEVERIFY
import org.bitcoins.core.script.reserved.OP_NOP
import org.bitcoins.core.script.splice.OP_SIZE

View file

@ -1,7 +1,10 @@
package org.bitcoins.core.serializers.transaction
import org.bitcoins.core.number.{Int32, UInt32}
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionConstants}
import org.bitcoins.core.protocol.transaction.{
Transaction,
TransactionConstants
}
import org.bitcoins.core.util.BitcoinSUtil
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
import scodec.bits.ByteVector

View file

@ -1,7 +1,10 @@
package org.bitcoins.core.serializers.transaction
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.transaction.{TransactionConstants, TransactionInput}
import org.bitcoins.core.protocol.transaction.{
TransactionConstants,
TransactionInput
}
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil}
import org.bitcoins.testkit.util.TestUtil
import org.scalatest.{FlatSpec, MustMatchers}

View file

@ -493,8 +493,9 @@ class BitcoinTxBuilderTest extends BitcoinSAsyncTest {
)
}
def verifyScript(tx: Transaction,
utxos: Vector[UTXOSpendingInfo]): Boolean = {
def verifyScript(
tx: Transaction,
utxos: Vector[UTXOSpendingInfo]): Boolean = {
val programs: Vector[PreExecutionScriptProgram] =
tx.inputs.zipWithIndex.toVector.map {
case (input: TransactionInput, idx: Int) =>

View file

@ -7,14 +7,17 @@ class TxoStateTest extends BitcoinSUnitTest {
behavior of "TxoState"
it must "read from string" in {
TxoState.fromString("doesnotexist").get must be (TxoState.DoesNotExist)
TxoState.fromString("doesnotexist").get must be(TxoState.DoesNotExist)
TxoState.fromString("PendingConfirmationsReceived").get must be (TxoState.PendingConfirmationsReceived)
TxoState.fromString("PendingConfirmationsReceived").get must be(
TxoState.PendingConfirmationsReceived)
TxoState.fromString("ConfirmedReceived").get must be (TxoState.ConfirmedReceived)
TxoState.fromString("ConfirmedReceived").get must be(
TxoState.ConfirmedReceived)
TxoState.fromString("PendingConfirmationsSpent").get must be (TxoState.PendingConfirmationsSpent)
TxoState.fromString("PendingConfirmationsSpent").get must be(
TxoState.PendingConfirmationsSpent)
TxoState.fromString("ConfirmedSpent").get must be (TxoState.ConfirmedSpent)
TxoState.fromString("ConfirmedSpent").get must be(TxoState.ConfirmedSpent)
}
}

View file

@ -12,27 +12,27 @@ import org.bitcoins.wallet.config.WalletAppConfig
import org.bitcoins.wallet.db.WalletDbManagement
class DbManagementTest extends BitcoinSUnitTest {
def dbConfig(project: ProjectType): Config = {
BitcoinSTestAppConfig.configWithMemoryDb(Some(project))
}
it must "run migrations for chain db" in {
val chainAppConfig = ChainAppConfig(BitcoinSTestAppConfig.tmpDir(),
dbConfig(ProjectType.Chain))
dbConfig(ProjectType.Chain))
val result = ChainDbManagement.migrate(chainAppConfig)
assert(result == 1)
}
it must "run migrations for wallet db" in {
val walletAppConfig = WalletAppConfig(BitcoinSTestAppConfig.tmpDir(),
dbConfig(ProjectType.Wallet))
dbConfig(ProjectType.Wallet))
val result = WalletDbManagement.migrate(walletAppConfig)
assert(result == 2)
}
it must "run migrations for node db" in {
val nodeAppConfig = NodeAppConfig(BitcoinSTestAppConfig.tmpDir(),
dbConfig(ProjectType.Node))
val nodeAppConfig =
NodeAppConfig(BitcoinSTestAppConfig.tmpDir(), dbConfig(ProjectType.Node))
val result = NodeDbManagement.migrate(nodeAppConfig)
assert(result == 1)
}

View file

@ -3,16 +3,17 @@ package org.bitcoins.keymanager
import java.nio.file.{Files, Path}
import org.bitcoins.core.crypto.{AesPassword, MnemonicCode}
import org.bitcoins.keymanager.ReadMnemonicError.{DecryptionError, JsonParsingError}
import org.bitcoins.keymanager.ReadMnemonicError.{
DecryptionError,
JsonParsingError
}
import org.bitcoins.testkit.Implicits._
import org.bitcoins.testkit.core.gen.CryptoGenerators
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.bitcoins.wallet.config.WalletAppConfig
import org.scalatest.{BeforeAndAfterEach, FutureOutcome}
class WalletStorageTest
extends BitcoinSWalletTest
with BeforeAndAfterEach {
class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
override type FixtureParam = WalletAppConfig
@ -37,21 +38,22 @@ class WalletStorageTest
mnemonic
}
it must "write and read a mnemonic to disk" in { walletConf: WalletAppConfig =>
assert(!walletConf.seedExists())
it must "write and read a mnemonic to disk" in {
walletConf: WalletAppConfig =>
assert(!walletConf.seedExists())
val writtenMnemonic = getAndWriteMnemonic(walletConf)
val writtenMnemonic = getAndWriteMnemonic(walletConf)
// should have been written by now
assert(walletConf.seedExists())
val seedPath = getSeedPath(walletConf)
val read =
WalletStorage.decryptMnemonicFromDisk(seedPath,passphrase)
read match {
case Right(readMnemonic) =>
assert(writtenMnemonic == readMnemonic)
case Left(err) => fail(err.toString)
}
// should have been written by now
assert(walletConf.seedExists())
val seedPath = getSeedPath(walletConf)
val read =
WalletStorage.decryptMnemonicFromDisk(seedPath, passphrase)
read match {
case Right(readMnemonic) =>
assert(writtenMnemonic == readMnemonic)
case Left(err) => fail(err.toString)
}
}
it must "fail to read a mnemonic with bad password" in { walletConf =>
@ -62,8 +64,8 @@ class WalletStorageTest
read match {
case Right(mnemonic) =>
fail("Wrote and read with different passwords")
case Left(DecryptionError) => succeed
case Left(err) => fail(err.toString)
case Left(DecryptionError) => succeed
case Left(err) => fail(err.toString)
}
}
@ -77,31 +79,30 @@ class WalletStorageTest
| }
""".stripMargin
val seedPath = getSeedPath(walletConf)
Files.write(seedPath,
badJson.getBytes())
Files.write(seedPath, badJson.getBytes())
val read =
WalletStorage.decryptMnemonicFromDisk(seedPath,passphrase)
WalletStorage.decryptMnemonicFromDisk(seedPath, passphrase)
read match {
case Left(JsonParsingError(_)) => succeed
case Left(JsonParsingError(_)) => succeed
case res @ (Left(_) | Right(_)) => fail(res.toString())
}
}
it must "throw an exception if we attempt to overwrite an existing seed" in { walletConf =>
it must "throw an exception if we attempt to overwrite an existing seed" in {
walletConf =>
assert(!walletConf.seedExists())
assert(!walletConf.seedExists())
val _ = getAndWriteMnemonic(walletConf)
val _ = getAndWriteMnemonic(walletConf)
// should have been written by now
assert(walletConf.seedExists())
// should have been written by now
assert(walletConf.seedExists())
assertThrows[RuntimeException] {
//attempt to write another mnemonic
getAndWriteMnemonic(walletConf)
}
assertThrows[RuntimeException] {
//attempt to write another mnemonic
getAndWriteMnemonic(walletConf)
}
}
}

View file

@ -8,29 +8,39 @@ import scodec.bits.BitVector
class BIP39KeyManagerTest extends KeyManagerUnitTest {
val purpose = HDPurposes.Legacy
//this is taken from 'trezor-addresses.json' which give us test cases that conform with trezor
val mnemonicStr ="stage boring net gather radar radio arrest eye ask risk girl country"
val mnemonicStr =
"stage boring net gather radar radio arrest eye ask risk girl country"
val mnemonic = MnemonicCode.fromWords(mnemonicStr.split(" ").toVector)
val coin = HDCoin(purpose,coinType = HDCoinType.Bitcoin)
val coin = HDCoin(purpose, coinType = HDCoinType.Bitcoin)
val hdAccount = HDAccount(coin, 0)
val path: HDPath = LegacyHDPath(coin.coinType,coin.purpose.constant,HDChainType.External,0)
val path: HDPath =
LegacyHDPath(coin.coinType, coin.purpose.constant, HDChainType.External, 0)
it must "initialize the key manager" in {
val entropy = MnemonicCode.getEntropy256Bits
val keyManager = withInitializedKeyManager(entropy = entropy)
val seedPath = keyManager.kmParams.seedPath
//verify we wrote the seed
assert(WalletStorage.seedExists(seedPath), "KeyManager did not write the seed to disk!")
assert(WalletStorage.seedExists(seedPath),
"KeyManager did not write the seed to disk!")
val decryptedE = WalletStorage.decryptMnemonicFromDisk(seedPath, KeyManagerTestUtil.badPassphrase)
val decryptedE =
WalletStorage.decryptMnemonicFromDisk(seedPath,
KeyManagerTestUtil.badPassphrase)
val mnemonic = decryptedE match {
case Right(m) => m
case Left(err) => fail(s"Failed to read mnemonic that was written by key manager with err=${err}")
case Left(err) =>
fail(
s"Failed to read mnemonic that was written by key manager with err=${err}")
}
assert(mnemonic.toEntropy == entropy, s"We did not read the same entropy that we wrote!")
assert(mnemonic.toEntropy == entropy,
s"We did not read the same entropy that we wrote!")
}
it must "initialize the key manager with a specific mnemonic" in {
@ -38,11 +48,11 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
val kmParams = buildParams()
val keyManager = withInitializedKeyManager(kmParams = kmParams,
entropy = mnemonic.toEntropy,
bip39PasswordOpt = None)
entropy = mnemonic.toEntropy,
bip39PasswordOpt = None)
keyManager.deriveXPub(hdAccount).get.toString must be ("xpub6D36zpm3tLPy3dBCpiScEpmmgsivFBcHxX5oXmPBW982BmLiEkjBEDdswxFUoeXpp272QuSpNKZ3f2TdEMkAHyCz1M7P3gFkYJJVEsM66SE")
keyManager.deriveXPub(hdAccount).get.toString must be(
"xpub6D36zpm3tLPy3dBCpiScEpmmgsivFBcHxX5oXmPBW982BmLiEkjBEDdswxFUoeXpp272QuSpNKZ3f2TdEMkAHyCz1M7P3gFkYJJVEsM66SE")
}
it must "initialize a key manager to the same xpub if we call constructor directly or use CreateKeyManagerApi" in {
@ -51,15 +61,17 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
val directXpub = direct.getRootXPub
val api = BIP39KeyManager.initializeWithEntropy(
entropy = mnemonic.toEntropy,
bip39PasswordOpt = None,
kmParams = kmParams).right.get
val api = BIP39KeyManager
.initializeWithEntropy(entropy = mnemonic.toEntropy,
bip39PasswordOpt = None,
kmParams = kmParams)
.right
.get
val apiXpub = api.getRootXPub
assert(apiXpub == directXpub, s"We don't have initialization symmetry between our constructors!")
assert(apiXpub == directXpub,
s"We don't have initialization symmetry between our constructors!")
//we should be able to derive the same child xpub
assert(api.deriveXPub(hdAccount) == direct.deriveXPub(hdAccount))
@ -68,19 +80,19 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
it must "initialize a key manager with a bip39 password to the same xpub if we call constructor directly or use CreateKeyManagerApi" in {
val kmParams = buildParams()
val bip39Pw = KeyManagerTestUtil.bip39Password
val direct = BIP39KeyManager(mnemonic, kmParams,Some(bip39Pw))
val direct = BIP39KeyManager(mnemonic, kmParams, Some(bip39Pw))
val directXpub = direct.getRootXPub
val api = BIP39KeyManager.initializeWithEntropy(
mnemonic.toEntropy,
Some(bip39Pw),
kmParams).right.get
val api = BIP39KeyManager
.initializeWithEntropy(mnemonic.toEntropy, Some(bip39Pw), kmParams)
.right
.get
val apiXpub = api.getRootXPub
assert(apiXpub == directXpub, s"We don't have initialization symmetry between our constructors!")
assert(apiXpub == directXpub,
s"We don't have initialization symmetry between our constructors!")
//we should be able to derive the same child xpub
assert(api.deriveXPub(hdAccount) == direct.deriveXPub(hdAccount))
@ -97,16 +109,18 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
val noPwXpub = noPassword.getRootXPub
assert(withPasswordXpub != noPwXpub, s"A key manager with a BIP39 passwrod should not generate the same xpub as a key manager without a password!")
assert(
withPasswordXpub != noPwXpub,
s"A key manager with a BIP39 passwrod should not generate the same xpub as a key manager without a password!")
}
it must "return a mnemonic not found if we have not initialized the key manager" in {
val kmParams = buildParams()
val kmE = BIP39KeyManager.fromParams(kmParams = kmParams,
password = BIP39KeyManager.badPassphrase,
bip39PasswordOpt = None)
password =
BIP39KeyManager.badPassphrase,
bip39PasswordOpt = None)
assert(kmE == Left(ReadMnemonicError.NotFoundError))
}
@ -116,13 +130,12 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
val hash = DoubleSha256DigestBE.empty.bytes
val signer = keyManager.toSign(path)
val sig = signer.sign(hash)
assert(signer.publicKey.verify(hash,sig))
assert(signer.publicKey.verify(hash, sig))
}
it must "throw an exception if entropy is bad" in {
val badEntropy = BitVector.empty
val init = BIP39KeyManager.initializeWithEntropy(
entropy = badEntropy,
bip39PasswordOpt = KeyManagerTestUtil.bip39PasswordOpt,
@ -133,6 +146,7 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
private def buildParams(): KeyManagerParams = {
KeyManagerParams(seedPath = KeyManagerTestUtil.tmpSeedPath,
purpose = purpose, network = MainNet)
purpose = purpose,
network = MainNet)
}
}

View file

@ -1,7 +1,11 @@
package org.bitcoins.keymanager.bip39
import org.bitcoins.core.crypto.AesPassword
import org.bitcoins.keymanager.{KeyManagerTestUtil, KeyManagerUnitTest, KeyManagerUnlockError}
import org.bitcoins.keymanager.{
KeyManagerTestUtil,
KeyManagerUnitTest,
KeyManagerUnlockError
}
class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
@ -9,35 +13,35 @@ class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
val bip39PwOpt = KeyManagerTestUtil.bip39PasswordOpt
val km = withInitializedKeyManager(bip39PasswordOpt = bip39PwOpt)
val unlockedE = BIP39LockedKeyManager.unlock(
KeyManagerTestUtil.badPassphrase,
bip39PasswordOpt = bip39PwOpt,
km.kmParams)
val unlockedE =
BIP39LockedKeyManager.unlock(KeyManagerTestUtil.badPassphrase,
bip39PasswordOpt = bip39PwOpt,
km.kmParams)
val unlockedKm = unlockedE match {
val unlockedKm = unlockedE match {
case Right(km) => km
case Left(err) => fail(s"Failed to unlock key manager ${err}")
}
assert(km == unlockedKm, s"Unlocked key manager must be the same was the pre-locked one")
assert(km == unlockedKm,
s"Unlocked key manager must be the same was the pre-locked one")
}
it must "fail to read bad json in the seed file" in {
val km = withInitializedKeyManager()
val badPassword = AesPassword.fromString("other bad password").get
val unlockedE = BIP39LockedKeyManager.unlock(passphrase = badPassword,
bip39PasswordOpt = None,
kmParams = km.kmParams)
bip39PasswordOpt = None,
kmParams = km.kmParams)
unlockedE match {
case Left(KeyManagerUnlockError.BadPassword) => succeed
case result @ (Left(_) | Right(_)) =>
fail(s"Expected to fail test with ${KeyManagerUnlockError.BadPassword} got ${result}")
fail(
s"Expected to fail test with ${KeyManagerUnlockError.BadPassword} got ${result}")
}
}
it must "fail if the seedPath is not found" in {
val badSeedPath = KeyManagerTestUtil.tmpSeedPath
val km = withInitializedKeyManager()
@ -49,7 +53,8 @@ class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
unlockedE match {
case Left(KeyManagerUnlockError.MnemonicNotFound) => succeed
case result @ (Left(_) | Right(_)) =>
fail(s"Expected to fail test with ${KeyManagerUnlockError.MnemonicNotFound} got ${result}")
fail(
s"Expected to fail test with ${KeyManagerUnlockError.MnemonicNotFound} got ${result}")
}
}
}

View file

@ -1,20 +1,38 @@
package org.bitcoins.keymanager.util
import org.bitcoins.core.config.{MainNet, TestNet3}
import org.bitcoins.core.crypto.ExtKeyVersion.{LegacyMainNetPriv, LegacyMainNetPub, LegacyTestNet3Priv, LegacyTestNet3Pub, NestedSegWitMainNetPriv, NestedSegWitMainNetPub, NestedSegWitTestNet3Priv, NestedSegWitTestNet3Pub, SegWitMainNetPriv, SegWitMainNetPub, SegWitTestNet3Priv, SegWitTestNet3Pub}
import org.bitcoins.core.crypto.ExtKeyVersion.{
LegacyMainNetPriv,
LegacyMainNetPub,
LegacyTestNet3Priv,
LegacyTestNet3Pub,
NestedSegWitMainNetPriv,
NestedSegWitMainNetPub,
NestedSegWitTestNet3Priv,
NestedSegWitTestNet3Pub,
SegWitMainNetPriv,
SegWitMainNetPub,
SegWitTestNet3Priv,
SegWitTestNet3Pub
}
import org.bitcoins.core.hd.{HDCoinType, HDPurpose, HDPurposes}
import org.bitcoins.keymanager.KeyManagerUnitTest
class HdUtilTest extends KeyManagerUnitTest {
it must "get the correct version for a public key" in {
assert(HDUtil.getXpubVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPub)
assert(HDUtil.getXpubVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Pub)
assert(HDUtil.getXpubVersion(HDPurposes.SegWit, MainNet) == SegWitMainNetPub)
assert(HDUtil.getXpubVersion(HDPurposes.SegWit, TestNet3) == SegWitTestNet3Pub)
assert(HDUtil.getXpubVersion(HDPurposes.NestedSegWit, MainNet) == NestedSegWitMainNetPub)
assert(HDUtil.getXpubVersion(HDPurposes.NestedSegWit, TestNet3) == NestedSegWitTestNet3Pub)
assert(
HDUtil.getXpubVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPub)
assert(
HDUtil.getXpubVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Pub)
assert(
HDUtil.getXpubVersion(HDPurposes.SegWit, MainNet) == SegWitMainNetPub)
assert(
HDUtil.getXpubVersion(HDPurposes.SegWit, TestNet3) == SegWitTestNet3Pub)
assert(
HDUtil.getXpubVersion(HDPurposes.NestedSegWit, MainNet) == NestedSegWitMainNetPub)
assert(
HDUtil.getXpubVersion(HDPurposes.NestedSegWit, TestNet3) == NestedSegWitTestNet3Pub)
assertThrows[IllegalArgumentException] {
HDUtil.getXpubVersion(HDPurpose(-1), TestNet3)
@ -22,12 +40,18 @@ class HdUtilTest extends KeyManagerUnitTest {
}
it must "get the correct version for a private key" in {
assert(HDUtil.getXprivVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPriv)
assert(HDUtil.getXprivVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Priv)
assert(HDUtil.getXprivVersion(HDPurposes.SegWit, MainNet) == SegWitMainNetPriv)
assert(HDUtil.getXprivVersion(HDPurposes.SegWit, TestNet3) == SegWitTestNet3Priv)
assert(HDUtil.getXprivVersion(HDPurposes.NestedSegWit, MainNet) == NestedSegWitMainNetPriv)
assert(HDUtil.getXprivVersion(HDPurposes.NestedSegWit, TestNet3) == NestedSegWitTestNet3Priv)
assert(
HDUtil.getXprivVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPriv)
assert(
HDUtil.getXprivVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Priv)
assert(
HDUtil.getXprivVersion(HDPurposes.SegWit, MainNet) == SegWitMainNetPriv)
assert(
HDUtil.getXprivVersion(HDPurposes.SegWit, TestNet3) == SegWitTestNet3Priv)
assert(
HDUtil.getXprivVersion(HDPurposes.NestedSegWit, MainNet) == NestedSegWitMainNetPriv)
assert(
HDUtil.getXprivVersion(HDPurposes.NestedSegWit, TestNet3) == NestedSegWitTestNet3Priv)
assertThrows[IllegalArgumentException] {
HDUtil.getXprivVersion(HDPurpose(-1), MainNet)
@ -39,22 +63,33 @@ class HdUtilTest extends KeyManagerUnitTest {
}
it must "find the corresponding priv version for a pubkey" in {
assert(HDUtil.getMatchingExtKeyVersion(LegacyMainNetPub) == LegacyMainNetPriv)
assert(HDUtil.getMatchingExtKeyVersion(LegacyTestNet3Pub) == LegacyTestNet3Priv)
assert(HDUtil.getMatchingExtKeyVersion(SegWitMainNetPub) == SegWitMainNetPriv)
assert(HDUtil.getMatchingExtKeyVersion(SegWitTestNet3Pub) == SegWitTestNet3Priv)
assert(HDUtil.getMatchingExtKeyVersion(NestedSegWitMainNetPub) == NestedSegWitMainNetPriv)
assert(HDUtil.getMatchingExtKeyVersion(NestedSegWitTestNet3Pub) == NestedSegWitTestNet3Priv)
assert(
HDUtil.getMatchingExtKeyVersion(LegacyMainNetPub) == LegacyMainNetPriv)
assert(
HDUtil.getMatchingExtKeyVersion(LegacyTestNet3Pub) == LegacyTestNet3Priv)
assert(
HDUtil.getMatchingExtKeyVersion(SegWitMainNetPub) == SegWitMainNetPriv)
assert(
HDUtil.getMatchingExtKeyVersion(SegWitTestNet3Pub) == SegWitTestNet3Priv)
assert(
HDUtil.getMatchingExtKeyVersion(NestedSegWitMainNetPub) == NestedSegWitMainNetPriv)
assert(
HDUtil.getMatchingExtKeyVersion(NestedSegWitTestNet3Pub) == NestedSegWitTestNet3Priv)
}
it must "find the corresponding pub version for a privkey" in {
assert(HDUtil.getMatchingExtKeyVersion(LegacyMainNetPriv) == LegacyMainNetPub)
assert(HDUtil.getMatchingExtKeyVersion(LegacyTestNet3Priv) == LegacyTestNet3Pub)
assert(HDUtil.getMatchingExtKeyVersion(SegWitMainNetPriv) == SegWitMainNetPub)
assert(HDUtil.getMatchingExtKeyVersion(SegWitTestNet3Priv) == SegWitTestNet3Pub)
assert(HDUtil.getMatchingExtKeyVersion(NestedSegWitMainNetPriv) == NestedSegWitMainNetPub)
assert(HDUtil.getMatchingExtKeyVersion(NestedSegWitTestNet3Priv) == NestedSegWitTestNet3Pub)
assert(
HDUtil.getMatchingExtKeyVersion(LegacyMainNetPriv) == LegacyMainNetPub)
assert(
HDUtil.getMatchingExtKeyVersion(LegacyTestNet3Priv) == LegacyTestNet3Pub)
assert(
HDUtil.getMatchingExtKeyVersion(SegWitMainNetPriv) == SegWitMainNetPub)
assert(
HDUtil.getMatchingExtKeyVersion(SegWitTestNet3Priv) == SegWitTestNet3Pub)
assert(
HDUtil.getMatchingExtKeyVersion(NestedSegWitMainNetPriv) == NestedSegWitMainNetPub)
assert(
HDUtil.getMatchingExtKeyVersion(NestedSegWitTestNet3Priv) == NestedSegWitTestNet3Pub)
}
it must "get the right coin type" in {

View file

@ -12,31 +12,36 @@ class AddressHandlingTest extends BitcoinSWalletTest {
behavior of "AddressHandling"
it must "generate a new address for the default account and then find it" in { wallet: Wallet =>
val addressF = wallet.getNewAddress()
it must "generate a new address for the default account and then find it" in {
wallet: Wallet =>
val addressF = wallet.getNewAddress()
for {
address <- addressF
exists <- wallet.contains(address, None)
} yield {
assert(exists, s"Wallet must contain address after generating it")
}
for {
address <- addressF
exists <- wallet.contains(address, None)
} yield {
assert(exists, s"Wallet must contain address after generating it")
}
}
it must "generate an address for a non default account and then find it" in { wallet: Wallet =>
val account1 = WalletTestUtil.getHdAccount1(wallet.walletConfig)
val addressF = wallet.getNewAddress(account1)
for {
address <- addressF
listAddressesForAcct <- wallet.listAddresses(account1)
exists <- wallet.contains(address, Some(account1))
doesNotExist <- wallet.contains(address, None)
} yield {
assert(listAddressesForAcct.nonEmpty)
assert(listAddressesForAcct.map(_.address).contains(address))
assert(exists, s"Wallet must contain address in specific after generating it")
assert(doesNotExist, s"Wallet must NOT contain address in default account when address is specified")
}
it must "generate an address for a non default account and then find it" in {
wallet: Wallet =>
val account1 = WalletTestUtil.getHdAccount1(wallet.walletConfig)
val addressF = wallet.getNewAddress(account1)
for {
address <- addressF
listAddressesForAcct <- wallet.listAddresses(account1)
exists <- wallet.contains(address, Some(account1))
doesNotExist <- wallet.contains(address, None)
} yield {
assert(listAddressesForAcct.nonEmpty)
assert(listAddressesForAcct.map(_.address).contains(address))
assert(exists,
s"Wallet must contain address in specific after generating it")
assert(
doesNotExist,
s"Wallet must NOT contain address in default account when address is specified")
}
}
}

View file

@ -15,89 +15,96 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
withFundedWallet(test)
}
val destination = TransactionOutput(Bitcoins(0.5),TestUtil.p2pkhScriptPubKey)
val destination = TransactionOutput(Bitcoins(0.5), TestUtil.p2pkhScriptPubKey)
val feeRate = SatoshisPerVirtualByte.one
it must "fund a simple raw transaction that requires one utxo" in { fundedWallet : FundedWallet =>
val wallet = fundedWallet.wallet
val fundedTxF = wallet.fundRawTransaction(
destinations = Vector(destination),
feeRate = feeRate)
for {
fundedTx <- fundedTxF
} yield {
assert(fundedTx.inputs.length == 1, s"We should only need one input to fund this tx")
assert(fundedTx.outputs.contains(destination))
assert(fundedTx.outputs.length == 2, s"We must have a single destination output and a change output")
}
it must "fund a simple raw transaction that requires one utxo" in {
fundedWallet: FundedWallet =>
val wallet = fundedWallet.wallet
val fundedTxF = wallet.fundRawTransaction(destinations =
Vector(destination),
feeRate = feeRate)
for {
fundedTx <- fundedTxF
} yield {
assert(fundedTx.inputs.length == 1,
s"We should only need one input to fund this tx")
assert(fundedTx.outputs.contains(destination))
assert(fundedTx.outputs.length == 2,
s"We must have a single destination output and a change output")
}
}
it must "fund a transaction that requires all utxos in our wallet" in { fundedWallet: FundedWallet =>
val amt = Bitcoins(5.5)
val newDestination = destination.copy(value = amt)
val wallet = fundedWallet.wallet
val fundedTxF = wallet.fundRawTransaction(
destinations = Vector(newDestination),
feeRate = feeRate)
for {
fundedTx <- fundedTxF
} yield {
assert(fundedTx.inputs.length == 3, s"We should need 3 inputs to fund this tx")
assert(fundedTx.outputs.contains(newDestination))
assert(fundedTx.outputs.length == 2, s"We must have a 2 destination output and a change output")
}
it must "fund a transaction that requires all utxos in our wallet" in {
fundedWallet: FundedWallet =>
val amt = Bitcoins(5.5)
val newDestination = destination.copy(value = amt)
val wallet = fundedWallet.wallet
val fundedTxF = wallet.fundRawTransaction(destinations =
Vector(newDestination),
feeRate = feeRate)
for {
fundedTx <- fundedTxF
} yield {
assert(fundedTx.inputs.length == 3,
s"We should need 3 inputs to fund this tx")
assert(fundedTx.outputs.contains(newDestination))
assert(fundedTx.outputs.length == 2,
s"We must have a 2 destination output and a change output")
}
}
it must "not care about the number of destinations" in { fundedWallet: FundedWallet =>
val destinations = Vector.fill(5)(destination)
it must "not care about the number of destinations" in {
fundedWallet: FundedWallet =>
val destinations = Vector.fill(5)(destination)
val wallet = fundedWallet.wallet
val fundedTxF = wallet.fundRawTransaction(
destinations = destinations,
feeRate = feeRate)
for {
fundedTx <- fundedTxF
} yield {
assert(fundedTx.inputs.length == 1, s"We should only need one input to fund this tx")
val wallet = fundedWallet.wallet
val fundedTxF = wallet.fundRawTransaction(destinations = destinations,
feeRate = feeRate)
for {
fundedTx <- fundedTxF
} yield {
assert(fundedTx.inputs.length == 1,
s"We should only need one input to fund this tx")
destinations.foreach(d =>
assert(fundedTx.outputs.contains(d))
)
assert(fundedTx.outputs.length == 6, s"We must have a 6 destination output and a change output")
}
destinations.foreach(d => assert(fundedTx.outputs.contains(d)))
assert(fundedTx.outputs.length == 6,
s"We must have a 6 destination output and a change output")
}
}
it must "fail to fund a raw transaction if we don't have enough money in our wallet" in { fundedWallet: FundedWallet =>
//our wallet should only have 6 bitcoin in it
val tooMuchMoney = Bitcoins(10)
val tooBigOutput = destination.copy(value = tooMuchMoney)
val wallet = fundedWallet.wallet
val fundedTxF = wallet.fundRawTransaction(
destinations = Vector(tooBigOutput),
feeRate = feeRate)
it must "fail to fund a raw transaction if we don't have enough money in our wallet" in {
fundedWallet: FundedWallet =>
//our wallet should only have 6 bitcoin in it
val tooMuchMoney = Bitcoins(10)
val tooBigOutput = destination.copy(value = tooMuchMoney)
val wallet = fundedWallet.wallet
val fundedTxF = wallet.fundRawTransaction(destinations =
Vector(tooBigOutput),
feeRate = feeRate)
recoverToSucceededIf[RuntimeException] {
fundedTxF
}
recoverToSucceededIf[RuntimeException] {
fundedTxF
}
}
it must "fail to fund a raw transaction if we have the _exact_ amount of money in the wallet because of the fee" in { fundedWallet: FundedWallet =>
//our wallet should only have 6 bitcoin in it
val tooMuchMoney = Bitcoins(6)
val tooBigOutput = destination.copy(value = tooMuchMoney)
val wallet = fundedWallet.wallet
it must "fail to fund a raw transaction if we have the _exact_ amount of money in the wallet because of the fee" in {
fundedWallet: FundedWallet =>
//our wallet should only have 6 bitcoin in it
val tooMuchMoney = Bitcoins(6)
val tooBigOutput = destination.copy(value = tooMuchMoney)
val wallet = fundedWallet.wallet
//6 bitcoin destination + 1 sat/vbyte fee means we should
//not have enough money for this
val fundedTxF = wallet.fundRawTransaction(
destinations = Vector(tooBigOutput),
feeRate = feeRate)
//6 bitcoin destination + 1 sat/vbyte fee means we should
//not have enough money for this
val fundedTxF = wallet.fundRawTransaction(destinations =
Vector(tooBigOutput),
feeRate = feeRate)
recoverToSucceededIf[RuntimeException] {
fundedTxF
}
recoverToSucceededIf[RuntimeException] {
fundedTxF
}
}
it must "fund from a specific account" in { fundedWallet: FundedWallet =>
@ -111,10 +118,9 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
val account1DbF = wallet.accountDAO.findByAccount(account1)
for {
account1DbOpt <- account1DbF
fundedTx <- wallet.fundRawTransaction(
Vector(newDestination),
feeRate,
account1DbOpt.get)
fundedTx <- wallet.fundRawTransaction(Vector(newDestination),
feeRate,
account1DbOpt.get)
} yield {
assert(fundedTx.inputs.nonEmpty)
assert(fundedTx.outputs.contains(newDestination))
@ -122,24 +128,24 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
}
}
it must "fail to fund from an account that does not have the funds" in { fundedWallet: FundedWallet =>
//account 1 should only have 1 btc in it
val amt = Bitcoins(1.1)
it must "fail to fund from an account that does not have the funds" in {
fundedWallet: FundedWallet =>
//account 1 should only have 1 btc in it
val amt = Bitcoins(1.1)
val newDestination = destination.copy(value = amt)
val wallet = fundedWallet.wallet
val account1 = WalletTestUtil.getHdAccount1(wallet.walletConfig)
val account1DbF = wallet.accountDAO.findByAccount(account1)
val fundedTxF = for {
account1DbOpt <- account1DbF
fundedTx <- wallet.fundRawTransaction(
Vector(newDestination),
feeRate,
account1DbOpt.get)
} yield fundedTx
val newDestination = destination.copy(value = amt)
val wallet = fundedWallet.wallet
val account1 = WalletTestUtil.getHdAccount1(wallet.walletConfig)
val account1DbF = wallet.accountDAO.findByAccount(account1)
val fundedTxF = for {
account1DbOpt <- account1DbF
fundedTx <- wallet.fundRawTransaction(Vector(newDestination),
feeRate,
account1DbOpt.get)
} yield fundedTx
recoverToSucceededIf[RuntimeException] {
fundedTxF
}
recoverToSucceededIf[RuntimeException] {
fundedTxF
}
}
}

View file

@ -11,7 +11,10 @@ import org.bitcoins.keymanager.bip39.BIP39KeyManager
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.fixtures.EmptyFixture
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.bitcoins.testkit.wallet.BitcoinSWalletTest.{MockChainQueryApi, MockNodeApi}
import org.bitcoins.testkit.wallet.BitcoinSWalletTest.{
MockChainQueryApi,
MockNodeApi
}
import org.bitcoins.wallet.config.WalletAppConfig
import org.bitcoins.wallet.models.{AccountDb, AddressDb}
import org.scalatest.compatible.Assertion
@ -134,17 +137,22 @@ class TrezorAddressTest extends BitcoinSWalletTest with EmptyFixture {
ConfigFactory.parseString(confStr)
}
private def getWallet(config: WalletAppConfig)(implicit ec: ExecutionContext): Future[Wallet] = {
private def getWallet(config: WalletAppConfig)(
implicit ec: ExecutionContext): Future[Wallet] = {
val bip39PasswordOpt = None
val kmE = BIP39KeyManager.initializeWithEntropy(entropy = mnemonic.toEntropy,
val kmE = BIP39KeyManager.initializeWithEntropy(
entropy = mnemonic.toEntropy,
bip39PasswordOpt = bip39PasswordOpt,
kmParams = config.kmParams)
kmE match {
case Left(err) => Future.failed(new RuntimeException(s"Failed to initialize km with err=${err}"))
case Left(err) =>
Future.failed(
new RuntimeException(s"Failed to initialize km with err=${err}"))
case Right(km) =>
val wallet = Wallet(km, MockNodeApi, MockChainQueryApi)(config, ec)
val walletF = Wallet.initialize(wallet = wallet,
bip39PasswordOpt = bip39PasswordOpt)(config,ec)
val walletF =
Wallet.initialize(wallet = wallet,
bip39PasswordOpt = bip39PasswordOpt)(config, ec)
walletF
}
}

View file

@ -64,8 +64,9 @@ class WalletUnitTest extends BitcoinSWalletTest {
it should "know what the last address index is" in { walletApi =>
val wallet = walletApi.asInstanceOf[Wallet]
def getMostRecent(hdAccount: HDAccount,
chain: HDChainType): Future[AddressDb] = {
def getMostRecent(
hdAccount: HDAccount,
chain: HDChainType): Future[AddressDb] = {
val recentOptFut: Future[Option[AddressDb]] = chain match {
case Change =>
wallet.addressDAO.findMostRecentChange(hdAccount)
@ -118,9 +119,7 @@ class WalletUnitTest extends BitcoinSWalletTest {
}
}
_ <- FutureUtil.sequentially(addrRange)(_ => getAddrFunc())
_ <- assertIndexIs(hdAccount,
chain,
addrIndex = addressesToGenerate)
_ <- assertIndexIs(hdAccount, chain, addrIndex = addressesToGenerate)
newest <- getAddrFunc()
res <- getMostRecent(hdAccount, chain).map { found =>
assert(found.address == newest)

View file

@ -6,7 +6,11 @@ import org.bitcoins.core.protocol.transaction.TransactionOutput
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerByte}
import org.bitcoins.core.wallet.utxo.TxoState
import org.bitcoins.testkit.Implicits._
import org.bitcoins.testkit.core.gen.{CryptoGenerators, TransactionGenerators, WitnessGenerators}
import org.bitcoins.testkit.core.gen.{
CryptoGenerators,
TransactionGenerators,
WitnessGenerators
}
import org.bitcoins.testkit.wallet.{BitcoinSWalletTest, WalletTestUtil}
import org.bitcoins.wallet.models.{SegwitV0SpendingInfo, SpendingInfoDb}
import org.scalatest.FutureOutcome

View file

@ -23,10 +23,10 @@ class AccountDAOTest extends BitcoinSWalletTest with WalletDAOFixture {
} yield assert(found.contains(created))
}
it must "find an account by HdAccount" in { daos =>
val accountDAO = daos.accountDAO
val account = WalletTestUtil.getHdAccount1(walletAppConfig = walletAppConfig)
val account =
WalletTestUtil.getHdAccount1(walletAppConfig = walletAppConfig)
for {
created <- {

View file

@ -1,7 +1,10 @@
package org.bitcoins.wallet.models
import org.bitcoins.core.protocol.script.ScriptSignature
import org.bitcoins.core.protocol.transaction.{BaseTransaction, TransactionInput}
import org.bitcoins.core.protocol.transaction.{
BaseTransaction,
TransactionInput
}
import org.bitcoins.core.wallet.utxo.TxoState
import org.bitcoins.testkit.Implicits._
import org.bitcoins.testkit.core.gen.TransactionGenerators
@ -75,9 +78,11 @@ class SpendingInfoDAOTest extends BitcoinSWalletTest with WalletDAOFixture {
val WalletDAOs(_, _, spendingInfoDAO) = daos
for {
utxo <- WalletTestUtil.insertSegWitUTXO(daos)
updated <- spendingInfoDAO.update(utxo.copy(state = TxoState.PendingConfirmationsReceived))
updated <- spendingInfoDAO.update(
utxo.copy(state = TxoState.PendingConfirmationsReceived))
unspent <- spendingInfoDAO.findAllUnspent()
updated <- spendingInfoDAO.updateTxoState(outputs = unspent.map(_.output),
updated <- spendingInfoDAO.updateTxoState(
outputs = unspent.map(_.output),
state = TxoState.PendingConfirmationsSpent)
unspentPostUpdate <- spendingInfoDAO.findAllUnspent()
} yield {