mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-19 05:25:11 +01:00
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:
parent
c968e79c80
commit
754aa77617
42 changed files with 490 additions and 311 deletions
|
@ -64,7 +64,7 @@ matrix:
|
||||||
name: Compile website and check formatting
|
name: Compile website and check formatting
|
||||||
script:
|
script:
|
||||||
- sbt docs/mdoc
|
- sbt docs/mdoc
|
||||||
- sbt scalafmtCheck
|
- sbt test:scalafmtCheck
|
||||||
|
|
||||||
# Release snapshots/versions of all libraries
|
# Release snapshots/versions of all libraries
|
||||||
# run ci-release only if previous stages passed
|
# run ci-release only if previous stages passed
|
||||||
|
|
|
@ -5,7 +5,10 @@ import java.io.File
|
||||||
import org.bitcoins.core.currency.Bitcoins
|
import org.bitcoins.core.currency.Bitcoins
|
||||||
import org.bitcoins.core.number.UInt32
|
import org.bitcoins.core.number.UInt32
|
||||||
import org.bitcoins.core.protocol.script.ScriptSignature
|
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.BitcoindRpcClient
|
||||||
import org.bitcoins.rpc.client.common.BitcoindVersion.V18
|
import org.bitcoins.rpc.client.common.BitcoindVersion.V18
|
||||||
import org.bitcoins.rpc.config.BitcoindInstance
|
import org.bitcoins.rpc.config.BitcoindInstance
|
||||||
|
|
|
@ -17,7 +17,8 @@ class ChainAppConfigTest extends ChainUnitTest {
|
||||||
//if we don't turn off logging here, isInitF a few lines down will
|
//if we don't turn off logging here, isInitF a few lines down will
|
||||||
//produce some nasty error logs since we are testing initialization
|
//produce some nasty error logs since we are testing initialization
|
||||||
//of the chain project
|
//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"
|
behavior of "ChainAppConfig"
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ class ECPrivateKeyTest extends BitcoinSUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "not serialize a ECPrivateKey toString" in {
|
it must "not serialize a ECPrivateKey toString" in {
|
||||||
ECPrivateKey().toString must be ("Masked(ECPrivateKeyImpl)")
|
ECPrivateKey().toString must be("Masked(ECPrivateKeyImpl)")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,8 +246,8 @@ class ExtKeyTest extends BitcoinSUnitTest {
|
||||||
val seedBytes =
|
val seedBytes =
|
||||||
hex"4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be"
|
hex"4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be"
|
||||||
|
|
||||||
val masterPriv = ExtPrivateKey(LegacyMainNetPriv,
|
val masterPriv =
|
||||||
Some(seedBytes), BIP32Path.empty)
|
ExtPrivateKey(LegacyMainNetPriv, Some(seedBytes), BIP32Path.empty)
|
||||||
masterPriv.toString must be (s"Masked(ExtPrivateKeyImpl)")
|
masterPriv.toString must be(s"Masked(ExtPrivateKeyImpl)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,19 @@ class ExtSignTest extends BitcoinSAsyncTest {
|
||||||
forAll(CryptoGenerators.extPrivateKey, CryptoGenerators.sha256Digest) {
|
forAll(CryptoGenerators.extPrivateKey, CryptoGenerators.sha256Digest) {
|
||||||
case (extPrivKey, hash) =>
|
case (extPrivKey, hash) =>
|
||||||
val sig = extPrivKey.sign(hash.bytes)
|
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 {
|
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) =>
|
case (extPrivKey, hash, path) =>
|
||||||
val sigF = extPrivKey.deriveAndSignFuture(hash.bytes,path)
|
val sigF = extPrivKey.deriveAndSignFuture(hash.bytes, path)
|
||||||
val childPubKey = extPrivKey.deriveChildPubKey(path).get
|
val childPubKey = extPrivKey.deriveChildPubKey(path).get
|
||||||
sigF.map { sig =>
|
sigF.map { sig =>
|
||||||
assert(childPubKey.key.verify(hash,sig))
|
assert(childPubKey.key.verify(hash, sig))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,8 +274,8 @@ class MnemonicCodeTest extends BitcoinSUnitTest {
|
||||||
|
|
||||||
val mnemonicCode = MnemonicCode.fromWords(correctSeed)
|
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(","))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ class FilterTypeTest extends BitcoinSUnitTest {
|
||||||
assert(FilterType.getCode(FilterType.Basic) == 0)
|
assert(FilterType.getCode(FilterType.Basic) == 0)
|
||||||
assert(FilterType.byCode(0) == FilterType.Basic)
|
assert(FilterType.byCode(0) == FilterType.Basic)
|
||||||
assertThrows[IllegalArgumentException](FilterType.byCode(1))
|
assertThrows[IllegalArgumentException](FilterType.byCode(1))
|
||||||
assertThrows[IllegalArgumentException](FilterType.getCode(FilterType.fromHex("ffff")))
|
assertThrows[IllegalArgumentException](
|
||||||
|
FilterType.getCode(FilterType.fromHex("ffff")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ class HDAccountTest extends BitcoinSUnitTest {
|
||||||
|
|
||||||
behavior of "HDAccount"
|
behavior of "HDAccount"
|
||||||
|
|
||||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration = {
|
implicit override val generatorDrivenConfig: PropertyCheckConfiguration = {
|
||||||
generatorDrivenConfigNewCode
|
generatorDrivenConfigNewCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,9 @@ class HDAccountTest extends BitcoinSUnitTest {
|
||||||
|
|
||||||
val isNotSame = !HDAccount.isSameAccount(missingLast, defaultAcct)
|
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 {
|
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)
|
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 {
|
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)
|
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 {
|
it must "fail with the empty path" in {
|
||||||
|
@ -58,7 +63,8 @@ class HDAccountTest extends BitcoinSUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "not taken an arbitrary path and arbitrary account and find them in the same account" in {
|
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) =>
|
forAll(HDGenerators.hdAccount, HDGenerators.bip32Path) {
|
||||||
|
case (acct, path) =>
|
||||||
assert(!HDAccount.isSameAccount(path, acct))
|
assert(!HDAccount.isSameAccount(path, acct))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,13 +39,22 @@ class ServiceIdentifierTest extends BitcoinSUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "correctly get a ServiceIdentifier from string" in {
|
it must "correctly get a ServiceIdentifier from string" in {
|
||||||
assert(ServiceIdentifier.fromString("NETWORK") == ServiceIdentifier.NODE_NETWORK)
|
assert(
|
||||||
assert(ServiceIdentifier.fromString("NETWORK_LIMITED") == ServiceIdentifier.NODE_NETWORK_LIMITED)
|
ServiceIdentifier.fromString("NETWORK") == ServiceIdentifier.NODE_NETWORK)
|
||||||
assert(ServiceIdentifier.fromString("WITNESS") == ServiceIdentifier.NODE_WITNESS)
|
assert(ServiceIdentifier
|
||||||
assert(ServiceIdentifier.fromString("BLOOM") == ServiceIdentifier.NODE_BLOOM)
|
.fromString("NETWORK_LIMITED") == ServiceIdentifier.NODE_NETWORK_LIMITED)
|
||||||
assert(ServiceIdentifier.fromString("GETUTXO") == ServiceIdentifier.NODE_GET_UTXO)
|
assert(
|
||||||
assert(ServiceIdentifier.fromString("COMPACT_FILTERS") == ServiceIdentifier.NODE_COMPACT_FILTERS)
|
ServiceIdentifier.fromString("WITNESS") == ServiceIdentifier.NODE_WITNESS)
|
||||||
assert(ServiceIdentifier.fromString("XTHIN") == ServiceIdentifier.NODE_XTHIN)
|
assert(
|
||||||
assertThrows[IllegalArgumentException](ServiceIdentifier.fromString("this is invalid"))
|
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"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,14 @@ package org.bitcoins.core.protocol
|
||||||
|
|
||||||
import org.bitcoins.core.config.{MainNet, RegTest, TestNet3}
|
import org.bitcoins.core.config.{MainNet, RegTest, TestNet3}
|
||||||
import org.bitcoins.core.crypto.{ECPublicKey, Sha256Hash160Digest}
|
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 org.bitcoins.testkit.util.BitcoinSUnitTest
|
||||||
|
|
||||||
import scala.util.{Failure, Success, Try}
|
import scala.util.{Failure, Success, Try}
|
||||||
|
|
|
@ -2,7 +2,12 @@ package org.bitcoins.core.protocol.script
|
||||||
|
|
||||||
import org.bitcoins.core.crypto.ECPrivateKey
|
import org.bitcoins.core.crypto.ECPrivateKey
|
||||||
import org.bitcoins.core.script.bitwise.OP_EQUALVERIFY
|
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.crypto.{OP_CHECKSIG, OP_HASH160}
|
||||||
import org.bitcoins.core.script.locktime.OP_CHECKLOCKTIMEVERIFY
|
import org.bitcoins.core.script.locktime.OP_CHECKLOCKTIMEVERIFY
|
||||||
import org.bitcoins.core.script.stack.{OP_DROP, OP_DUP}
|
import org.bitcoins.core.script.stack.{OP_DROP, OP_DUP}
|
||||||
|
|
|
@ -2,7 +2,12 @@ package org.bitcoins.core.protocol.script
|
||||||
|
|
||||||
import org.bitcoins.core.crypto.ECPrivateKey
|
import org.bitcoins.core.crypto.ECPrivateKey
|
||||||
import org.bitcoins.core.script.bitwise.OP_EQUALVERIFY
|
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.crypto.{OP_CHECKSIG, OP_HASH160}
|
||||||
import org.bitcoins.core.script.locktime.OP_CHECKSEQUENCEVERIFY
|
import org.bitcoins.core.script.locktime.OP_CHECKSEQUENCEVERIFY
|
||||||
import org.bitcoins.core.script.stack.{OP_DROP, OP_DUP}
|
import org.bitcoins.core.script.stack.{OP_DROP, OP_DUP}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package org.bitcoins.core.protocol.script
|
package org.bitcoins.core.protocol.script
|
||||||
|
|
||||||
import org.bitcoins.core.crypto.ECPublicKey
|
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.core.util.BitcoinSLogger
|
||||||
import org.bitcoins.testkit.util.TestUtil
|
import org.bitcoins.testkit.util.TestUtil
|
||||||
import org.scalatest.{FlatSpec, MustMatchers}
|
import org.scalatest.{FlatSpec, MustMatchers}
|
||||||
|
|
|
@ -5,7 +5,12 @@ import org.bitcoins.core.currency.CurrencyUnits
|
||||||
import org.bitcoins.core.number.Int32
|
import org.bitcoins.core.number.Int32
|
||||||
import org.bitcoins.core.policy.Policy
|
import org.bitcoins.core.policy.Policy
|
||||||
import org.bitcoins.core.protocol.script.testprotocol.SignatureHashTestCase
|
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.script.crypto.{HashType, SIGHASH_ALL}
|
||||||
import org.bitcoins.core.serializers.script.RawScriptSignatureParser
|
import org.bitcoins.core.serializers.script.RawScriptSignatureParser
|
||||||
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil}
|
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package org.bitcoins.core.protocol.transaction
|
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}
|
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package org.bitcoins.core.protocol.transaction
|
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.currency.CurrencyUnits
|
||||||
import org.bitcoins.core.number.UInt32
|
import org.bitcoins.core.number.UInt32
|
||||||
import org.bitcoins.core.protocol.script._
|
import org.bitcoins.core.protocol.script._
|
||||||
|
|
|
@ -3,7 +3,10 @@ package org.bitcoins.core.script.arithmetic
|
||||||
import org.bitcoins.core.script.constant._
|
import org.bitcoins.core.script.constant._
|
||||||
import org.bitcoins.core.script.flag.ScriptFlag
|
import org.bitcoins.core.script.flag.ScriptFlag
|
||||||
import org.bitcoins.core.script.result._
|
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.core.util.ScriptProgramTestUtil
|
||||||
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,10 @@ package org.bitcoins.core.script.constant
|
||||||
import org.bitcoins.core.script.bitwise.OP_EQUAL
|
import org.bitcoins.core.script.bitwise.OP_EQUAL
|
||||||
import org.bitcoins.core.script.crypto.OP_CHECKMULTISIGVERIFY
|
import org.bitcoins.core.script.crypto.OP_CHECKMULTISIGVERIFY
|
||||||
import org.bitcoins.core.script.flag.{ScriptFlag, ScriptVerifyMinimalData}
|
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.core.util.ScriptProgramTestUtil
|
||||||
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
package org.bitcoins.core.script.control
|
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.arithmetic.OP_ADD
|
||||||
import org.bitcoins.core.script.bitwise.OP_EQUAL
|
import org.bitcoins.core.script.bitwise.OP_EQUAL
|
||||||
import org.bitcoins.core.script.constant._
|
import org.bitcoins.core.script.constant._
|
||||||
import org.bitcoins.core.script.reserved.{OP_RESERVED, OP_VER}
|
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.serializers.script.ScriptParser
|
||||||
import org.bitcoins.core.util._
|
import org.bitcoins.core.util._
|
||||||
import org.bitcoins.testkit.util.TestUtil
|
import org.bitcoins.testkit.util.TestUtil
|
||||||
|
|
|
@ -7,7 +7,11 @@ import org.bitcoins.core.protocol.script.ScriptSignature
|
||||||
import org.bitcoins.core.protocol.transaction._
|
import org.bitcoins.core.protocol.transaction._
|
||||||
import org.bitcoins.core.script._
|
import org.bitcoins.core.script._
|
||||||
import org.bitcoins.core.script.constant._
|
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.script.result._
|
||||||
import org.bitcoins.core.util.{BitcoinSLogger, ScriptProgramTestUtil}
|
import org.bitcoins.core.util.{BitcoinSLogger, ScriptProgramTestUtil}
|
||||||
import org.bitcoins.testkit.util.TestUtil
|
import org.bitcoins.testkit.util.TestUtil
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
package org.bitcoins.core.script.interpreter
|
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.currency.CurrencyUnits
|
||||||
import org.bitcoins.core.protocol.script._
|
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.PreExecutionScriptProgram
|
||||||
import org.bitcoins.core.script.flag.ScriptFlagFactory
|
import org.bitcoins.core.script.flag.ScriptFlagFactory
|
||||||
import org.bitcoins.core.script.interpreter.testprotocol.CoreTestCase
|
import org.bitcoins.core.script.interpreter.testprotocol.CoreTestCase
|
||||||
|
|
|
@ -6,7 +6,10 @@ import org.bitcoins.core.number.UInt32
|
||||||
import org.bitcoins.core.protocol.transaction._
|
import org.bitcoins.core.protocol.transaction._
|
||||||
import org.bitcoins.core.script.constant.{OP_0, ScriptNumber}
|
import org.bitcoins.core.script.constant.{OP_0, ScriptNumber}
|
||||||
import org.bitcoins.core.script.result._
|
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.core.util.ScriptProgramTestUtil
|
||||||
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@ class RawScriptSignatureParserTest extends BitcoinSUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "read an EmptyScriptSignature" in {
|
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 {
|
it must "read then write a raw script sig" in {
|
||||||
|
|
|
@ -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.bitwise.{OP_EQUAL, OP_EQUALVERIFY}
|
||||||
import org.bitcoins.core.script.constant._
|
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.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.locktime.OP_CHECKLOCKTIMEVERIFY
|
||||||
import org.bitcoins.core.script.reserved.OP_NOP
|
import org.bitcoins.core.script.reserved.OP_NOP
|
||||||
import org.bitcoins.core.script.splice.OP_SIZE
|
import org.bitcoins.core.script.splice.OP_SIZE
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package org.bitcoins.core.serializers.transaction
|
package org.bitcoins.core.serializers.transaction
|
||||||
|
|
||||||
import org.bitcoins.core.number.{Int32, UInt32}
|
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.core.util.BitcoinSUtil
|
||||||
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
import org.bitcoins.testkit.util.{BitcoinSUnitTest, TestUtil}
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package org.bitcoins.core.serializers.transaction
|
package org.bitcoins.core.serializers.transaction
|
||||||
|
|
||||||
import org.bitcoins.core.number.UInt32
|
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.core.util.{BitcoinSLogger, BitcoinSUtil}
|
||||||
import org.bitcoins.testkit.util.TestUtil
|
import org.bitcoins.testkit.util.TestUtil
|
||||||
import org.scalatest.{FlatSpec, MustMatchers}
|
import org.scalatest.{FlatSpec, MustMatchers}
|
||||||
|
|
|
@ -493,7 +493,8 @@ class BitcoinTxBuilderTest extends BitcoinSAsyncTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def verifyScript(tx: Transaction,
|
def verifyScript(
|
||||||
|
tx: Transaction,
|
||||||
utxos: Vector[UTXOSpendingInfo]): Boolean = {
|
utxos: Vector[UTXOSpendingInfo]): Boolean = {
|
||||||
val programs: Vector[PreExecutionScriptProgram] =
|
val programs: Vector[PreExecutionScriptProgram] =
|
||||||
tx.inputs.zipWithIndex.toVector.map {
|
tx.inputs.zipWithIndex.toVector.map {
|
||||||
|
|
|
@ -7,14 +7,17 @@ class TxoStateTest extends BitcoinSUnitTest {
|
||||||
behavior of "TxoState"
|
behavior of "TxoState"
|
||||||
|
|
||||||
it must "read from string" in {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.bitcoins.wallet.config.WalletAppConfig
|
||||||
import org.bitcoins.wallet.db.WalletDbManagement
|
import org.bitcoins.wallet.db.WalletDbManagement
|
||||||
|
|
||||||
class DbManagementTest extends BitcoinSUnitTest {
|
class DbManagementTest extends BitcoinSUnitTest {
|
||||||
|
|
||||||
def dbConfig(project: ProjectType): Config = {
|
def dbConfig(project: ProjectType): Config = {
|
||||||
BitcoinSTestAppConfig.configWithMemoryDb(Some(project))
|
BitcoinSTestAppConfig.configWithMemoryDb(Some(project))
|
||||||
}
|
}
|
||||||
|
@ -29,10 +30,9 @@ class DbManagementTest extends BitcoinSUnitTest {
|
||||||
assert(result == 2)
|
assert(result == 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
it must "run migrations for node db" in {
|
it must "run migrations for node db" in {
|
||||||
val nodeAppConfig = NodeAppConfig(BitcoinSTestAppConfig.tmpDir(),
|
val nodeAppConfig =
|
||||||
dbConfig(ProjectType.Node))
|
NodeAppConfig(BitcoinSTestAppConfig.tmpDir(), dbConfig(ProjectType.Node))
|
||||||
val result = NodeDbManagement.migrate(nodeAppConfig)
|
val result = NodeDbManagement.migrate(nodeAppConfig)
|
||||||
assert(result == 1)
|
assert(result == 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,17 @@ package org.bitcoins.keymanager
|
||||||
import java.nio.file.{Files, Path}
|
import java.nio.file.{Files, Path}
|
||||||
|
|
||||||
import org.bitcoins.core.crypto.{AesPassword, MnemonicCode}
|
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.Implicits._
|
||||||
import org.bitcoins.testkit.core.gen.CryptoGenerators
|
import org.bitcoins.testkit.core.gen.CryptoGenerators
|
||||||
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
|
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
|
||||||
import org.bitcoins.wallet.config.WalletAppConfig
|
import org.bitcoins.wallet.config.WalletAppConfig
|
||||||
import org.scalatest.{BeforeAndAfterEach, FutureOutcome}
|
import org.scalatest.{BeforeAndAfterEach, FutureOutcome}
|
||||||
|
|
||||||
class WalletStorageTest
|
class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||||
extends BitcoinSWalletTest
|
|
||||||
with BeforeAndAfterEach {
|
|
||||||
|
|
||||||
override type FixtureParam = WalletAppConfig
|
override type FixtureParam = WalletAppConfig
|
||||||
|
|
||||||
|
@ -37,7 +38,8 @@ class WalletStorageTest
|
||||||
mnemonic
|
mnemonic
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "write and read a mnemonic to disk" in { walletConf: WalletAppConfig =>
|
it must "write and read a mnemonic to disk" in {
|
||||||
|
walletConf: WalletAppConfig =>
|
||||||
assert(!walletConf.seedExists())
|
assert(!walletConf.seedExists())
|
||||||
|
|
||||||
val writtenMnemonic = getAndWriteMnemonic(walletConf)
|
val writtenMnemonic = getAndWriteMnemonic(walletConf)
|
||||||
|
@ -46,7 +48,7 @@ class WalletStorageTest
|
||||||
assert(walletConf.seedExists())
|
assert(walletConf.seedExists())
|
||||||
val seedPath = getSeedPath(walletConf)
|
val seedPath = getSeedPath(walletConf)
|
||||||
val read =
|
val read =
|
||||||
WalletStorage.decryptMnemonicFromDisk(seedPath,passphrase)
|
WalletStorage.decryptMnemonicFromDisk(seedPath, passphrase)
|
||||||
read match {
|
read match {
|
||||||
case Right(readMnemonic) =>
|
case Right(readMnemonic) =>
|
||||||
assert(writtenMnemonic == readMnemonic)
|
assert(writtenMnemonic == readMnemonic)
|
||||||
|
@ -77,11 +79,10 @@ class WalletStorageTest
|
||||||
| }
|
| }
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
val seedPath = getSeedPath(walletConf)
|
val seedPath = getSeedPath(walletConf)
|
||||||
Files.write(seedPath,
|
Files.write(seedPath, badJson.getBytes())
|
||||||
badJson.getBytes())
|
|
||||||
|
|
||||||
val read =
|
val read =
|
||||||
WalletStorage.decryptMnemonicFromDisk(seedPath,passphrase)
|
WalletStorage.decryptMnemonicFromDisk(seedPath, passphrase)
|
||||||
|
|
||||||
read match {
|
read match {
|
||||||
case Left(JsonParsingError(_)) => succeed
|
case Left(JsonParsingError(_)) => succeed
|
||||||
|
@ -89,8 +90,8 @@ class WalletStorageTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -8,29 +8,39 @@ import scodec.bits.BitVector
|
||||||
|
|
||||||
class BIP39KeyManagerTest extends KeyManagerUnitTest {
|
class BIP39KeyManagerTest extends KeyManagerUnitTest {
|
||||||
val purpose = HDPurposes.Legacy
|
val purpose = HDPurposes.Legacy
|
||||||
|
|
||||||
//this is taken from 'trezor-addresses.json' which give us test cases that conform with trezor
|
//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 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 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 {
|
it must "initialize the key manager" in {
|
||||||
val entropy = MnemonicCode.getEntropy256Bits
|
val entropy = MnemonicCode.getEntropy256Bits
|
||||||
val keyManager = withInitializedKeyManager(entropy = entropy)
|
val keyManager = withInitializedKeyManager(entropy = entropy)
|
||||||
val seedPath = keyManager.kmParams.seedPath
|
val seedPath = keyManager.kmParams.seedPath
|
||||||
//verify we wrote the seed
|
//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 {
|
val mnemonic = decryptedE match {
|
||||||
case Right(m) => m
|
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 {
|
it must "initialize the key manager with a specific mnemonic" in {
|
||||||
|
@ -41,8 +51,8 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
|
||||||
entropy = mnemonic.toEntropy,
|
entropy = mnemonic.toEntropy,
|
||||||
bip39PasswordOpt = None)
|
bip39PasswordOpt = None)
|
||||||
|
|
||||||
|
keyManager.deriveXPub(hdAccount).get.toString must be(
|
||||||
keyManager.deriveXPub(hdAccount).get.toString must be ("xpub6D36zpm3tLPy3dBCpiScEpmmgsivFBcHxX5oXmPBW982BmLiEkjBEDdswxFUoeXpp272QuSpNKZ3f2TdEMkAHyCz1M7P3gFkYJJVEsM66SE")
|
"xpub6D36zpm3tLPy3dBCpiScEpmmgsivFBcHxX5oXmPBW982BmLiEkjBEDdswxFUoeXpp272QuSpNKZ3f2TdEMkAHyCz1M7P3gFkYJJVEsM66SE")
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "initialize a key manager to the same xpub if we call constructor directly or use CreateKeyManagerApi" in {
|
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 directXpub = direct.getRootXPub
|
||||||
|
|
||||||
val api = BIP39KeyManager.initializeWithEntropy(
|
val api = BIP39KeyManager
|
||||||
entropy = mnemonic.toEntropy,
|
.initializeWithEntropy(entropy = mnemonic.toEntropy,
|
||||||
bip39PasswordOpt = None,
|
bip39PasswordOpt = None,
|
||||||
kmParams = kmParams).right.get
|
kmParams = kmParams)
|
||||||
|
.right
|
||||||
|
.get
|
||||||
|
|
||||||
val apiXpub = api.getRootXPub
|
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
|
//we should be able to derive the same child xpub
|
||||||
assert(api.deriveXPub(hdAccount) == direct.deriveXPub(hdAccount))
|
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 {
|
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 kmParams = buildParams()
|
||||||
val bip39Pw = KeyManagerTestUtil.bip39Password
|
val bip39Pw = KeyManagerTestUtil.bip39Password
|
||||||
val direct = BIP39KeyManager(mnemonic, kmParams,Some(bip39Pw))
|
val direct = BIP39KeyManager(mnemonic, kmParams, Some(bip39Pw))
|
||||||
|
|
||||||
val directXpub = direct.getRootXPub
|
val directXpub = direct.getRootXPub
|
||||||
|
|
||||||
val api = BIP39KeyManager.initializeWithEntropy(
|
val api = BIP39KeyManager
|
||||||
mnemonic.toEntropy,
|
.initializeWithEntropy(mnemonic.toEntropy, Some(bip39Pw), kmParams)
|
||||||
Some(bip39Pw),
|
.right
|
||||||
kmParams).right.get
|
.get
|
||||||
|
|
||||||
val apiXpub = api.getRootXPub
|
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
|
//we should be able to derive the same child xpub
|
||||||
assert(api.deriveXPub(hdAccount) == direct.deriveXPub(hdAccount))
|
assert(api.deriveXPub(hdAccount) == direct.deriveXPub(hdAccount))
|
||||||
|
@ -97,15 +109,17 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
|
||||||
|
|
||||||
val noPwXpub = noPassword.getRootXPub
|
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 {
|
it must "return a mnemonic not found if we have not initialized the key manager" in {
|
||||||
val kmParams = buildParams()
|
val kmParams = buildParams()
|
||||||
val kmE = BIP39KeyManager.fromParams(kmParams = kmParams,
|
val kmE = BIP39KeyManager.fromParams(kmParams = kmParams,
|
||||||
password = BIP39KeyManager.badPassphrase,
|
password =
|
||||||
|
BIP39KeyManager.badPassphrase,
|
||||||
bip39PasswordOpt = None)
|
bip39PasswordOpt = None)
|
||||||
|
|
||||||
assert(kmE == Left(ReadMnemonicError.NotFoundError))
|
assert(kmE == Left(ReadMnemonicError.NotFoundError))
|
||||||
|
@ -116,13 +130,12 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
|
||||||
val hash = DoubleSha256DigestBE.empty.bytes
|
val hash = DoubleSha256DigestBE.empty.bytes
|
||||||
val signer = keyManager.toSign(path)
|
val signer = keyManager.toSign(path)
|
||||||
val sig = signer.sign(hash)
|
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 {
|
it must "throw an exception if entropy is bad" in {
|
||||||
val badEntropy = BitVector.empty
|
val badEntropy = BitVector.empty
|
||||||
|
|
||||||
|
|
||||||
val init = BIP39KeyManager.initializeWithEntropy(
|
val init = BIP39KeyManager.initializeWithEntropy(
|
||||||
entropy = badEntropy,
|
entropy = badEntropy,
|
||||||
bip39PasswordOpt = KeyManagerTestUtil.bip39PasswordOpt,
|
bip39PasswordOpt = KeyManagerTestUtil.bip39PasswordOpt,
|
||||||
|
@ -133,6 +146,7 @@ class BIP39KeyManagerTest extends KeyManagerUnitTest {
|
||||||
|
|
||||||
private def buildParams(): KeyManagerParams = {
|
private def buildParams(): KeyManagerParams = {
|
||||||
KeyManagerParams(seedPath = KeyManagerTestUtil.tmpSeedPath,
|
KeyManagerParams(seedPath = KeyManagerTestUtil.tmpSeedPath,
|
||||||
purpose = purpose, network = MainNet)
|
purpose = purpose,
|
||||||
|
network = MainNet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package org.bitcoins.keymanager.bip39
|
package org.bitcoins.keymanager.bip39
|
||||||
|
|
||||||
import org.bitcoins.core.crypto.AesPassword
|
import org.bitcoins.core.crypto.AesPassword
|
||||||
import org.bitcoins.keymanager.{KeyManagerTestUtil, KeyManagerUnitTest, KeyManagerUnlockError}
|
import org.bitcoins.keymanager.{
|
||||||
|
KeyManagerTestUtil,
|
||||||
|
KeyManagerUnitTest,
|
||||||
|
KeyManagerUnlockError
|
||||||
|
}
|
||||||
|
|
||||||
class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
|
class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
|
||||||
|
|
||||||
|
@ -9,8 +13,8 @@ class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
|
||||||
val bip39PwOpt = KeyManagerTestUtil.bip39PasswordOpt
|
val bip39PwOpt = KeyManagerTestUtil.bip39PasswordOpt
|
||||||
val km = withInitializedKeyManager(bip39PasswordOpt = bip39PwOpt)
|
val km = withInitializedKeyManager(bip39PasswordOpt = bip39PwOpt)
|
||||||
|
|
||||||
val unlockedE = BIP39LockedKeyManager.unlock(
|
val unlockedE =
|
||||||
KeyManagerTestUtil.badPassphrase,
|
BIP39LockedKeyManager.unlock(KeyManagerTestUtil.badPassphrase,
|
||||||
bip39PasswordOpt = bip39PwOpt,
|
bip39PasswordOpt = bip39PwOpt,
|
||||||
km.kmParams)
|
km.kmParams)
|
||||||
|
|
||||||
|
@ -19,10 +23,10 @@ class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
|
||||||
case Left(err) => fail(s"Failed to unlock key manager ${err}")
|
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 {
|
it must "fail to read bad json in the seed file" in {
|
||||||
val km = withInitializedKeyManager()
|
val km = withInitializedKeyManager()
|
||||||
val badPassword = AesPassword.fromString("other bad password").get
|
val badPassword = AesPassword.fromString("other bad password").get
|
||||||
|
@ -33,11 +37,11 @@ class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
|
||||||
unlockedE match {
|
unlockedE match {
|
||||||
case Left(KeyManagerUnlockError.BadPassword) => succeed
|
case Left(KeyManagerUnlockError.BadPassword) => succeed
|
||||||
case result @ (Left(_) | Right(_)) =>
|
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 {
|
it must "fail if the seedPath is not found" in {
|
||||||
val badSeedPath = KeyManagerTestUtil.tmpSeedPath
|
val badSeedPath = KeyManagerTestUtil.tmpSeedPath
|
||||||
val km = withInitializedKeyManager()
|
val km = withInitializedKeyManager()
|
||||||
|
@ -49,7 +53,8 @@ class BIP39LockedKeyManagerTest extends KeyManagerUnitTest {
|
||||||
unlockedE match {
|
unlockedE match {
|
||||||
case Left(KeyManagerUnlockError.MnemonicNotFound) => succeed
|
case Left(KeyManagerUnlockError.MnemonicNotFound) => succeed
|
||||||
case result @ (Left(_) | Right(_)) =>
|
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}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,38 @@
|
||||||
package org.bitcoins.keymanager.util
|
package org.bitcoins.keymanager.util
|
||||||
|
|
||||||
import org.bitcoins.core.config.{MainNet, TestNet3}
|
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.core.hd.{HDCoinType, HDPurpose, HDPurposes}
|
||||||
import org.bitcoins.keymanager.KeyManagerUnitTest
|
import org.bitcoins.keymanager.KeyManagerUnitTest
|
||||||
|
|
||||||
class HdUtilTest extends KeyManagerUnitTest {
|
class HdUtilTest extends KeyManagerUnitTest {
|
||||||
|
|
||||||
|
|
||||||
it must "get the correct version for a public key" in {
|
it must "get the correct version for a public key" in {
|
||||||
assert(HDUtil.getXpubVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPub)
|
assert(
|
||||||
assert(HDUtil.getXpubVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Pub)
|
HDUtil.getXpubVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPub)
|
||||||
assert(HDUtil.getXpubVersion(HDPurposes.SegWit, MainNet) == SegWitMainNetPub)
|
assert(
|
||||||
assert(HDUtil.getXpubVersion(HDPurposes.SegWit, TestNet3) == SegWitTestNet3Pub)
|
HDUtil.getXpubVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Pub)
|
||||||
assert(HDUtil.getXpubVersion(HDPurposes.NestedSegWit, MainNet) == NestedSegWitMainNetPub)
|
assert(
|
||||||
assert(HDUtil.getXpubVersion(HDPurposes.NestedSegWit, TestNet3) == NestedSegWitTestNet3Pub)
|
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] {
|
assertThrows[IllegalArgumentException] {
|
||||||
HDUtil.getXpubVersion(HDPurpose(-1), TestNet3)
|
HDUtil.getXpubVersion(HDPurpose(-1), TestNet3)
|
||||||
|
@ -22,12 +40,18 @@ class HdUtilTest extends KeyManagerUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "get the correct version for a private key" in {
|
it must "get the correct version for a private key" in {
|
||||||
assert(HDUtil.getXprivVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPriv)
|
assert(
|
||||||
assert(HDUtil.getXprivVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Priv)
|
HDUtil.getXprivVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPriv)
|
||||||
assert(HDUtil.getXprivVersion(HDPurposes.SegWit, MainNet) == SegWitMainNetPriv)
|
assert(
|
||||||
assert(HDUtil.getXprivVersion(HDPurposes.SegWit, TestNet3) == SegWitTestNet3Priv)
|
HDUtil.getXprivVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Priv)
|
||||||
assert(HDUtil.getXprivVersion(HDPurposes.NestedSegWit, MainNet) == NestedSegWitMainNetPriv)
|
assert(
|
||||||
assert(HDUtil.getXprivVersion(HDPurposes.NestedSegWit, TestNet3) == NestedSegWitTestNet3Priv)
|
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] {
|
assertThrows[IllegalArgumentException] {
|
||||||
HDUtil.getXprivVersion(HDPurpose(-1), MainNet)
|
HDUtil.getXprivVersion(HDPurpose(-1), MainNet)
|
||||||
|
@ -39,22 +63,33 @@ class HdUtilTest extends KeyManagerUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "find the corresponding priv version for a pubkey" in {
|
it must "find the corresponding priv version for a pubkey" in {
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(LegacyMainNetPub) == LegacyMainNetPriv)
|
assert(
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(LegacyTestNet3Pub) == LegacyTestNet3Priv)
|
HDUtil.getMatchingExtKeyVersion(LegacyMainNetPub) == LegacyMainNetPriv)
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(SegWitMainNetPub) == SegWitMainNetPriv)
|
assert(
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(SegWitTestNet3Pub) == SegWitTestNet3Priv)
|
HDUtil.getMatchingExtKeyVersion(LegacyTestNet3Pub) == LegacyTestNet3Priv)
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(NestedSegWitMainNetPub) == NestedSegWitMainNetPriv)
|
assert(
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(NestedSegWitTestNet3Pub) == NestedSegWitTestNet3Priv)
|
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 {
|
it must "find the corresponding pub version for a privkey" in {
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(LegacyMainNetPriv) == LegacyMainNetPub)
|
assert(
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(LegacyTestNet3Priv) == LegacyTestNet3Pub)
|
HDUtil.getMatchingExtKeyVersion(LegacyMainNetPriv) == LegacyMainNetPub)
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(SegWitMainNetPriv) == SegWitMainNetPub)
|
assert(
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(SegWitTestNet3Priv) == SegWitTestNet3Pub)
|
HDUtil.getMatchingExtKeyVersion(LegacyTestNet3Priv) == LegacyTestNet3Pub)
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(NestedSegWitMainNetPriv) == NestedSegWitMainNetPub)
|
assert(
|
||||||
assert(HDUtil.getMatchingExtKeyVersion(NestedSegWitTestNet3Priv) == NestedSegWitTestNet3Pub)
|
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 {
|
it must "get the right coin type" in {
|
||||||
|
|
|
@ -12,7 +12,8 @@ class AddressHandlingTest extends BitcoinSWalletTest {
|
||||||
|
|
||||||
behavior of "AddressHandling"
|
behavior of "AddressHandling"
|
||||||
|
|
||||||
it must "generate a new address for the default account and then find it" in { wallet: Wallet =>
|
it must "generate a new address for the default account and then find it" in {
|
||||||
|
wallet: Wallet =>
|
||||||
val addressF = wallet.getNewAddress()
|
val addressF = wallet.getNewAddress()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -23,7 +24,8 @@ class AddressHandlingTest extends BitcoinSWalletTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "generate an address for a non default account and then find it" in { wallet: Wallet =>
|
it must "generate an address for a non default account and then find it" in {
|
||||||
|
wallet: Wallet =>
|
||||||
val account1 = WalletTestUtil.getHdAccount1(wallet.walletConfig)
|
val account1 = WalletTestUtil.getHdAccount1(wallet.walletConfig)
|
||||||
val addressF = wallet.getNewAddress(account1)
|
val addressF = wallet.getNewAddress(account1)
|
||||||
for {
|
for {
|
||||||
|
@ -34,8 +36,11 @@ class AddressHandlingTest extends BitcoinSWalletTest {
|
||||||
} yield {
|
} yield {
|
||||||
assert(listAddressesForAcct.nonEmpty)
|
assert(listAddressesForAcct.nonEmpty)
|
||||||
assert(listAddressesForAcct.map(_.address).contains(address))
|
assert(listAddressesForAcct.map(_.address).contains(address))
|
||||||
assert(exists, s"Wallet must contain address in specific after generating it")
|
assert(exists,
|
||||||
assert(doesNotExist, s"Wallet must NOT contain address in default account when address is specified")
|
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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,67 +15,73 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
|
||||||
withFundedWallet(test)
|
withFundedWallet(test)
|
||||||
}
|
}
|
||||||
|
|
||||||
val destination = TransactionOutput(Bitcoins(0.5),TestUtil.p2pkhScriptPubKey)
|
val destination = TransactionOutput(Bitcoins(0.5), TestUtil.p2pkhScriptPubKey)
|
||||||
val feeRate = SatoshisPerVirtualByte.one
|
val feeRate = SatoshisPerVirtualByte.one
|
||||||
|
|
||||||
it must "fund a simple raw transaction that requires one utxo" in { fundedWallet : FundedWallet =>
|
it must "fund a simple raw transaction that requires one utxo" in {
|
||||||
|
fundedWallet: FundedWallet =>
|
||||||
val wallet = fundedWallet.wallet
|
val wallet = fundedWallet.wallet
|
||||||
val fundedTxF = wallet.fundRawTransaction(
|
val fundedTxF = wallet.fundRawTransaction(destinations =
|
||||||
destinations = Vector(destination),
|
Vector(destination),
|
||||||
feeRate = feeRate)
|
feeRate = feeRate)
|
||||||
for {
|
for {
|
||||||
fundedTx <- fundedTxF
|
fundedTx <- fundedTxF
|
||||||
} yield {
|
} yield {
|
||||||
assert(fundedTx.inputs.length == 1, s"We should only need one input to fund this tx")
|
assert(fundedTx.inputs.length == 1,
|
||||||
|
s"We should only need one input to fund this tx")
|
||||||
assert(fundedTx.outputs.contains(destination))
|
assert(fundedTx.outputs.contains(destination))
|
||||||
assert(fundedTx.outputs.length == 2, s"We must have a single destination output and a change output")
|
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 =>
|
it must "fund a transaction that requires all utxos in our wallet" in {
|
||||||
|
fundedWallet: FundedWallet =>
|
||||||
val amt = Bitcoins(5.5)
|
val amt = Bitcoins(5.5)
|
||||||
val newDestination = destination.copy(value = amt)
|
val newDestination = destination.copy(value = amt)
|
||||||
val wallet = fundedWallet.wallet
|
val wallet = fundedWallet.wallet
|
||||||
val fundedTxF = wallet.fundRawTransaction(
|
val fundedTxF = wallet.fundRawTransaction(destinations =
|
||||||
destinations = Vector(newDestination),
|
Vector(newDestination),
|
||||||
feeRate = feeRate)
|
feeRate = feeRate)
|
||||||
for {
|
for {
|
||||||
fundedTx <- fundedTxF
|
fundedTx <- fundedTxF
|
||||||
} yield {
|
} yield {
|
||||||
assert(fundedTx.inputs.length == 3, s"We should need 3 inputs to fund this tx")
|
assert(fundedTx.inputs.length == 3,
|
||||||
|
s"We should need 3 inputs to fund this tx")
|
||||||
assert(fundedTx.outputs.contains(newDestination))
|
assert(fundedTx.outputs.contains(newDestination))
|
||||||
assert(fundedTx.outputs.length == 2, s"We must have a 2 destination output and a change output")
|
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 =>
|
it must "not care about the number of destinations" in {
|
||||||
|
fundedWallet: FundedWallet =>
|
||||||
val destinations = Vector.fill(5)(destination)
|
val destinations = Vector.fill(5)(destination)
|
||||||
|
|
||||||
val wallet = fundedWallet.wallet
|
val wallet = fundedWallet.wallet
|
||||||
val fundedTxF = wallet.fundRawTransaction(
|
val fundedTxF = wallet.fundRawTransaction(destinations = destinations,
|
||||||
destinations = destinations,
|
|
||||||
feeRate = feeRate)
|
feeRate = feeRate)
|
||||||
for {
|
for {
|
||||||
fundedTx <- fundedTxF
|
fundedTx <- fundedTxF
|
||||||
} yield {
|
} yield {
|
||||||
assert(fundedTx.inputs.length == 1, s"We should only need one input to fund this tx")
|
assert(fundedTx.inputs.length == 1,
|
||||||
|
s"We should only need one input to fund this tx")
|
||||||
|
|
||||||
destinations.foreach(d =>
|
destinations.foreach(d => assert(fundedTx.outputs.contains(d)))
|
||||||
assert(fundedTx.outputs.contains(d))
|
assert(fundedTx.outputs.length == 6,
|
||||||
)
|
s"We must have a 6 destination output and a change output")
|
||||||
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 =>
|
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
|
//our wallet should only have 6 bitcoin in it
|
||||||
val tooMuchMoney = Bitcoins(10)
|
val tooMuchMoney = Bitcoins(10)
|
||||||
val tooBigOutput = destination.copy(value = tooMuchMoney)
|
val tooBigOutput = destination.copy(value = tooMuchMoney)
|
||||||
val wallet = fundedWallet.wallet
|
val wallet = fundedWallet.wallet
|
||||||
val fundedTxF = wallet.fundRawTransaction(
|
val fundedTxF = wallet.fundRawTransaction(destinations =
|
||||||
destinations = Vector(tooBigOutput),
|
Vector(tooBigOutput),
|
||||||
feeRate = feeRate)
|
feeRate = feeRate)
|
||||||
|
|
||||||
recoverToSucceededIf[RuntimeException] {
|
recoverToSucceededIf[RuntimeException] {
|
||||||
|
@ -83,7 +89,8 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 =>
|
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
|
//our wallet should only have 6 bitcoin in it
|
||||||
val tooMuchMoney = Bitcoins(6)
|
val tooMuchMoney = Bitcoins(6)
|
||||||
val tooBigOutput = destination.copy(value = tooMuchMoney)
|
val tooBigOutput = destination.copy(value = tooMuchMoney)
|
||||||
|
@ -91,8 +98,8 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
|
||||||
|
|
||||||
//6 bitcoin destination + 1 sat/vbyte fee means we should
|
//6 bitcoin destination + 1 sat/vbyte fee means we should
|
||||||
//not have enough money for this
|
//not have enough money for this
|
||||||
val fundedTxF = wallet.fundRawTransaction(
|
val fundedTxF = wallet.fundRawTransaction(destinations =
|
||||||
destinations = Vector(tooBigOutput),
|
Vector(tooBigOutput),
|
||||||
feeRate = feeRate)
|
feeRate = feeRate)
|
||||||
|
|
||||||
recoverToSucceededIf[RuntimeException] {
|
recoverToSucceededIf[RuntimeException] {
|
||||||
|
@ -111,8 +118,7 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
|
||||||
val account1DbF = wallet.accountDAO.findByAccount(account1)
|
val account1DbF = wallet.accountDAO.findByAccount(account1)
|
||||||
for {
|
for {
|
||||||
account1DbOpt <- account1DbF
|
account1DbOpt <- account1DbF
|
||||||
fundedTx <- wallet.fundRawTransaction(
|
fundedTx <- wallet.fundRawTransaction(Vector(newDestination),
|
||||||
Vector(newDestination),
|
|
||||||
feeRate,
|
feeRate,
|
||||||
account1DbOpt.get)
|
account1DbOpt.get)
|
||||||
} yield {
|
} yield {
|
||||||
|
@ -122,7 +128,8 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it must "fail to fund from an account that does not have the funds" in { fundedWallet: FundedWallet =>
|
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
|
//account 1 should only have 1 btc in it
|
||||||
val amt = Bitcoins(1.1)
|
val amt = Bitcoins(1.1)
|
||||||
|
|
||||||
|
@ -132,8 +139,7 @@ class FundTransactionHandlingTest extends BitcoinSWalletTest {
|
||||||
val account1DbF = wallet.accountDAO.findByAccount(account1)
|
val account1DbF = wallet.accountDAO.findByAccount(account1)
|
||||||
val fundedTxF = for {
|
val fundedTxF = for {
|
||||||
account1DbOpt <- account1DbF
|
account1DbOpt <- account1DbF
|
||||||
fundedTx <- wallet.fundRawTransaction(
|
fundedTx <- wallet.fundRawTransaction(Vector(newDestination),
|
||||||
Vector(newDestination),
|
|
||||||
feeRate,
|
feeRate,
|
||||||
account1DbOpt.get)
|
account1DbOpt.get)
|
||||||
} yield fundedTx
|
} yield fundedTx
|
||||||
|
|
|
@ -11,7 +11,10 @@ import org.bitcoins.keymanager.bip39.BIP39KeyManager
|
||||||
import org.bitcoins.testkit.BitcoinSTestAppConfig
|
import org.bitcoins.testkit.BitcoinSTestAppConfig
|
||||||
import org.bitcoins.testkit.fixtures.EmptyFixture
|
import org.bitcoins.testkit.fixtures.EmptyFixture
|
||||||
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
|
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.config.WalletAppConfig
|
||||||
import org.bitcoins.wallet.models.{AccountDb, AddressDb}
|
import org.bitcoins.wallet.models.{AccountDb, AddressDb}
|
||||||
import org.scalatest.compatible.Assertion
|
import org.scalatest.compatible.Assertion
|
||||||
|
@ -134,17 +137,22 @@ class TrezorAddressTest extends BitcoinSWalletTest with EmptyFixture {
|
||||||
ConfigFactory.parseString(confStr)
|
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 bip39PasswordOpt = None
|
||||||
val kmE = BIP39KeyManager.initializeWithEntropy(entropy = mnemonic.toEntropy,
|
val kmE = BIP39KeyManager.initializeWithEntropy(
|
||||||
|
entropy = mnemonic.toEntropy,
|
||||||
bip39PasswordOpt = bip39PasswordOpt,
|
bip39PasswordOpt = bip39PasswordOpt,
|
||||||
kmParams = config.kmParams)
|
kmParams = config.kmParams)
|
||||||
kmE match {
|
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) =>
|
case Right(km) =>
|
||||||
val wallet = Wallet(km, MockNodeApi, MockChainQueryApi)(config, ec)
|
val wallet = Wallet(km, MockNodeApi, MockChainQueryApi)(config, ec)
|
||||||
val walletF = Wallet.initialize(wallet = wallet,
|
val walletF =
|
||||||
bip39PasswordOpt = bip39PasswordOpt)(config,ec)
|
Wallet.initialize(wallet = wallet,
|
||||||
|
bip39PasswordOpt = bip39PasswordOpt)(config, ec)
|
||||||
walletF
|
walletF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,8 @@ class WalletUnitTest extends BitcoinSWalletTest {
|
||||||
it should "know what the last address index is" in { walletApi =>
|
it should "know what the last address index is" in { walletApi =>
|
||||||
val wallet = walletApi.asInstanceOf[Wallet]
|
val wallet = walletApi.asInstanceOf[Wallet]
|
||||||
|
|
||||||
def getMostRecent(hdAccount: HDAccount,
|
def getMostRecent(
|
||||||
|
hdAccount: HDAccount,
|
||||||
chain: HDChainType): Future[AddressDb] = {
|
chain: HDChainType): Future[AddressDb] = {
|
||||||
val recentOptFut: Future[Option[AddressDb]] = chain match {
|
val recentOptFut: Future[Option[AddressDb]] = chain match {
|
||||||
case Change =>
|
case Change =>
|
||||||
|
@ -118,9 +119,7 @@ class WalletUnitTest extends BitcoinSWalletTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ <- FutureUtil.sequentially(addrRange)(_ => getAddrFunc())
|
_ <- FutureUtil.sequentially(addrRange)(_ => getAddrFunc())
|
||||||
_ <- assertIndexIs(hdAccount,
|
_ <- assertIndexIs(hdAccount, chain, addrIndex = addressesToGenerate)
|
||||||
chain,
|
|
||||||
addrIndex = addressesToGenerate)
|
|
||||||
newest <- getAddrFunc()
|
newest <- getAddrFunc()
|
||||||
res <- getMostRecent(hdAccount, chain).map { found =>
|
res <- getMostRecent(hdAccount, chain).map { found =>
|
||||||
assert(found.address == newest)
|
assert(found.address == newest)
|
||||||
|
|
|
@ -6,7 +6,11 @@ import org.bitcoins.core.protocol.transaction.TransactionOutput
|
||||||
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerByte}
|
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerByte}
|
||||||
import org.bitcoins.core.wallet.utxo.TxoState
|
import org.bitcoins.core.wallet.utxo.TxoState
|
||||||
import org.bitcoins.testkit.Implicits._
|
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.testkit.wallet.{BitcoinSWalletTest, WalletTestUtil}
|
||||||
import org.bitcoins.wallet.models.{SegwitV0SpendingInfo, SpendingInfoDb}
|
import org.bitcoins.wallet.models.{SegwitV0SpendingInfo, SpendingInfoDb}
|
||||||
import org.scalatest.FutureOutcome
|
import org.scalatest.FutureOutcome
|
||||||
|
|
|
@ -23,10 +23,10 @@ class AccountDAOTest extends BitcoinSWalletTest with WalletDAOFixture {
|
||||||
} yield assert(found.contains(created))
|
} yield assert(found.contains(created))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
it must "find an account by HdAccount" in { daos =>
|
it must "find an account by HdAccount" in { daos =>
|
||||||
val accountDAO = daos.accountDAO
|
val accountDAO = daos.accountDAO
|
||||||
val account = WalletTestUtil.getHdAccount1(walletAppConfig = walletAppConfig)
|
val account =
|
||||||
|
WalletTestUtil.getHdAccount1(walletAppConfig = walletAppConfig)
|
||||||
for {
|
for {
|
||||||
created <- {
|
created <- {
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package org.bitcoins.wallet.models
|
package org.bitcoins.wallet.models
|
||||||
|
|
||||||
import org.bitcoins.core.protocol.script.ScriptSignature
|
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.core.wallet.utxo.TxoState
|
||||||
import org.bitcoins.testkit.Implicits._
|
import org.bitcoins.testkit.Implicits._
|
||||||
import org.bitcoins.testkit.core.gen.TransactionGenerators
|
import org.bitcoins.testkit.core.gen.TransactionGenerators
|
||||||
|
@ -75,9 +78,11 @@ class SpendingInfoDAOTest extends BitcoinSWalletTest with WalletDAOFixture {
|
||||||
val WalletDAOs(_, _, spendingInfoDAO) = daos
|
val WalletDAOs(_, _, spendingInfoDAO) = daos
|
||||||
for {
|
for {
|
||||||
utxo <- WalletTestUtil.insertSegWitUTXO(daos)
|
utxo <- WalletTestUtil.insertSegWitUTXO(daos)
|
||||||
updated <- spendingInfoDAO.update(utxo.copy(state = TxoState.PendingConfirmationsReceived))
|
updated <- spendingInfoDAO.update(
|
||||||
|
utxo.copy(state = TxoState.PendingConfirmationsReceived))
|
||||||
unspent <- spendingInfoDAO.findAllUnspent()
|
unspent <- spendingInfoDAO.findAllUnspent()
|
||||||
updated <- spendingInfoDAO.updateTxoState(outputs = unspent.map(_.output),
|
updated <- spendingInfoDAO.updateTxoState(
|
||||||
|
outputs = unspent.map(_.output),
|
||||||
state = TxoState.PendingConfirmationsSpent)
|
state = TxoState.PendingConfirmationsSpent)
|
||||||
unspentPostUpdate <- spendingInfoDAO.findAllUnspent()
|
unspentPostUpdate <- spendingInfoDAO.findAllUnspent()
|
||||||
} yield {
|
} yield {
|
||||||
|
|
Loading…
Add table
Reference in a new issue