Move MockChainQueryApi/MockNodeApi out of BaseWalletTest (#4542)

* Move MockChainQueryApi/NodeApi out of BaseWalletTest

* fix docs

* Move wallet configurations out of BaseWalletTest

* Move helper methods out of BitcoinSFixture trait into companion object to simplify the hierarchy

* Refactor usage of WalletWithBitcoind to allow parameterization of the BitcoindRpcClient type
This commit is contained in:
Chris Stewart 2022-07-27 10:18:22 -05:00 committed by GitHub
parent 6c76639ba3
commit b69e487d04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 367 additions and 357 deletions

View File

@ -13,6 +13,7 @@ import org.bitcoins.core.protocol.transaction.{
import org.bitcoins.crypto.{ECAdaptorSignature, ECPublicKey, Sha256Digest}
import org.bitcoins.db.CRUD
import org.bitcoins.dlc.wallet.models._
import org.bitcoins.testkit.chain.MockChainQueryApi
import org.bitcoins.testkit.fixtures.DLCDAOFixture
import org.bitcoins.testkit.wallet.{BitcoinSWalletTest, DLCWalletUtil}
import org.scalatest.Assertion
@ -78,7 +79,8 @@ class DLCDAOTest extends BitcoinSWalletTest with DLCDAOFixture {
isInitiator = true,
index = 0,
inputSerialId = UInt64.zero,
outPoint = TransactionOutPoint(testBlockHash, UInt32.zero),
outPoint =
TransactionOutPoint(MockChainQueryApi.testBlockHash, UInt32.zero),
output = TransactionOutput(Satoshis.one, EmptyScriptPubKey),
nSequence = TransactionConstants.enableRBFSequence,
maxWitnessLength = 107,
@ -100,7 +102,8 @@ class DLCDAOTest extends BitcoinSWalletTest with DLCDAOFixture {
isInitiator = true,
index = 0,
inputSerialId = UInt64.zero,
outPoint = TransactionOutPoint(testBlockHash, UInt32.zero),
outPoint =
TransactionOutPoint(MockChainQueryApi.testBlockHash, UInt32.zero),
output = TransactionOutput(Satoshis.one, EmptyScriptPubKey),
nSequence = TransactionConstants.enableRBFSequence,
maxWitnessLength = 107,
@ -112,7 +115,8 @@ class DLCDAOTest extends BitcoinSWalletTest with DLCDAOFixture {
isInitiator = false,
index = 0,
inputSerialId = UInt64.one,
outPoint = TransactionOutPoint(testBlockHash, UInt32.one),
outPoint =
TransactionOutPoint(MockChainQueryApi.testBlockHash, UInt32.one),
output = TransactionOutput(Satoshis.one, EmptyScriptPubKey),
nSequence = TransactionConstants.enableRBFSequence,
maxWitnessLength = 107,
@ -124,7 +128,8 @@ class DLCDAOTest extends BitcoinSWalletTest with DLCDAOFixture {
isInitiator = true,
index = 1,
inputSerialId = UInt64(2),
outPoint = TransactionOutPoint(testBlockHash, UInt32(3)),
outPoint =
TransactionOutPoint(MockChainQueryApi.testBlockHash, UInt32(3)),
output = TransactionOutput(Satoshis.one, EmptyScriptPubKey),
nSequence = TransactionConstants.enableRBFSequence,
maxWitnessLength = 107,

View File

@ -6,7 +6,9 @@ import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
import org.bitcoins.core.wallet.utxo.TxoState
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.chain.MockChainQueryApi
import org.bitcoins.testkit.keymanager.KeyManagerTestUtil.bip39PasswordOpt
import org.bitcoins.testkit.node.MockNodeApi
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.bitcoins.testkit.wallet.BitcoinSWalletTest._
import org.bitcoins.testkit.wallet.DLCWalletUtil._

View File

@ -18,7 +18,8 @@ import org.bitcoins.node._
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
import org.bitcoins.rpc.config._
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
org.bitcoins.testkit.chain.MockChainQueryApi
import org.bitcoins.testkit.node.MockNodeApi
import org.bitcoins.wallet.Wallet
import org.bitcoins.wallet.config.WalletAppConfig
@ -78,7 +79,7 @@ implicit val walletConf: WalletAppConfig =
// and a ChainApi
val instance = BitcoindInstanceLocal.fromConfigFile(BitcoindConfig.DEFAULT_CONF_FILE)
val bitcoind = BitcoindV19RpcClient(instance)
val nodeApi = BitcoinSWalletTest.MockNodeApi
val nodeApi = MockNodeApi.mock
// This function can be used to create a callback for when our chain api receives a transaction, block, or
// a block filter, the returned NodeCallbacks will contain the necessary items to initialize the callbacks

View File

@ -18,6 +18,7 @@ import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.bitcoins.wallet.Wallet
import org.bitcoins.wallet.config.WalletAppConfig
import org.bitcoins.testkit.chain.MockChainQueryApi
import scala.concurrent.{ExecutionContextExecutor, Future}
@ -55,7 +56,7 @@ implicit val walletConf: WalletAppConfig =
// and a ChainApi
val instance = BitcoindInstanceLocal.fromConfigFile(BitcoindConfig.DEFAULT_CONF_FILE)
val bitcoind = BitcoindV19RpcClient(instance)
val chainApi = BitcoinSWalletTest.MockChainQueryApi
val chainApi = MockChainQueryApi.mock
val aesPasswordOpt = Some(AesPassword.fromString("password"))
// This function can be used to create a callback for when our node api calls downloadBlocks,

View File

@ -144,7 +144,7 @@ trait ChainUnitTest
itVerbString: ItVerbString): SugaryItVerbString =
new SugaryItVerbString(itVerbString)
/** Fixture that creates a [[org.bitcoins.chain.models.BlockHeaderTable]]
/** Fixture that creates a block header table
* with one row inserted into it, the [[org.bitcoins.core.protocol.blockchain.RegTestNetChainParams]]
* genesis block
*/
@ -285,9 +285,10 @@ trait ChainUnitTest
}
def createBitcoindChainHandlerViaZmq(): Future[BitcoindChainHandlerViaZmq] = {
composeBuildersAndWrap(() => BitcoinSFixture.createBitcoind(),
createChainHandlerWithBitcoindZmq,
BitcoindChainHandlerViaZmq.apply)()
BitcoinSFixture.composeBuildersAndWrap(
() => BitcoinSFixture.createBitcoind(),
createChainHandlerWithBitcoindZmq,
BitcoindChainHandlerViaZmq.apply)(executionContext)()
}
def destroyBitcoindChainHandlerViaZmq(
@ -314,7 +315,7 @@ trait ChainUnitTest
system: ActorSystem,
chainAppConfig: ChainAppConfig): FutureOutcome = {
val builder: () => Future[BitcoindChainHandlerViaZmq] =
composeBuildersAndWrap(
BitcoinSFixture.composeBuildersAndWrap(
builder = () => BitcoinSFixture.createBitcoind(),
dependentBuilder = { rpc: BitcoindRpcClient =>
createChainHandlerWithBitcoindZmq(rpc)(chainAppConfig)
@ -643,7 +644,6 @@ object ChainUnitTest extends ChainVerificationLogger {
_ <- appConfig.dropAll()
} yield ()
/** Creates the [[org.bitcoins.chain.models.BlockHeaderTable]] and inserts the genesis header */
def setupHeaderTableWithGenesisHeader()(implicit
ec: ExecutionContext,
appConfig: ChainAppConfig): Future[

View File

@ -0,0 +1,100 @@
package org.bitcoins.testkit.chain
import org.bitcoins.core.api.chain.ChainQueryApi
import org.bitcoins.core.api.chain.ChainQueryApi.FilterResponse
import org.bitcoins.core.gcs.BlockFilter
import org.bitcoins.core.protocol.BlockStamp
import org.bitcoins.core.protocol.blockchain.RegTestNetChainParams
import org.bitcoins.core.util.FutureUtil
import org.bitcoins.crypto.DoubleSha256DigestBE
import scala.concurrent.Future
object MockChainQueryApi extends ChainQueryApi {
val mock: ChainQueryApi = this
// This is a random block on testnet
val testBlockHash: DoubleSha256DigestBE = DoubleSha256DigestBE.fromHex(
"00000000496dcc754fabd97f3e2df0a7337eab417d75537fecf97a7ebb0e7c75")
/** Gets the height of the given block */
override def getBlockHeight(
blockHash: DoubleSha256DigestBE): Future[Option[Int]] = {
if (blockHash == testBlockHash) {
Future.successful(Some(1))
} else if (
blockHash == RegTestNetChainParams.genesisBlock.blockHeader.hashBE
) {
Future.successful(Some(1))
} else FutureUtil.none
}
/** Gets the hash of the block that is what we consider "best" */
override def getBestBlockHash(): Future[DoubleSha256DigestBE] =
Future.successful(testBlockHash)
/** Gets number of confirmations for the given block hash */
override def getNumberOfConfirmations(
blockHash: DoubleSha256DigestBE): Future[Option[Int]] = {
if (blockHash == testBlockHash) {
Future.successful(Some(6))
} else FutureUtil.none
}
/** Gets the number of compact filters in the database */
override def getFilterCount(): Future[Int] = Future.successful(1)
/** Returns the block height of the given block stamp */
override def getHeightByBlockStamp(blockStamp: BlockStamp): Future[Int] =
Future.successful(1)
override def getFiltersBetweenHeights(
startHeight: Int,
endHeight: Int): Future[Vector[FilterResponse]] =
Future.successful {
import scodec.bits._
// This is a filter for the random block on testnet
val filterBytes: ByteVector =
hex"fd2701f0ed169ad16107a8a74609b9e4de3c6133c564f79923ca228805d3" ++
hex"8e3efc796c4b35034cb573b10b759cdda5efd19e1cdb4d343afcb06455fa" ++
hex"820b06eca828ad61d3377fa464f3bd06ff4432310a363f667e13d09ba993" ++
hex"264c703a0aa668b33eaa555bd3e93ac85dfde380ab723aafd407dfa13ffe" ++
hex"2e7ddf6f452bd0d977617c4ab2dc3b38c26810023984ad57890e3cf34cfc" ++
hex"2d4a6973b9430ede26bfd9f5bb24e043d48483d84b9025d0a940b15f13fc" ++
hex"0a1e77abd7626869f417c7710e9a6315477691d7c4e2c50f0e776755a62a" ++
hex"b6f0e8eb7a3be8d1a8c3d9dd4602efc5146f0d431d1669378d7afa03c7b9" ++
hex"84d9b0b78007abb6e7c036156e5186d1d79a2f37daecfcbe8821cf42851c" ++
hex"b10ef0c359307d54e53078eb631f02c067a474dceb484da20bc0e7c5451a" ++
hex"b957f46b306caa82938b19bb34fd76c5cc07e048932524704dec8f72c91c" ++
hex"d5ee1f4648de839047a0bea0d4d4d66c19cfccc2b5f285a84af18114f608" ++
hex"f144391648aedfb5ffcccbb51272512d6ba9a2e19a47cebe5b50a8a7073a" ++
hex"1c24059440444047a41bdbab16f61bc4b0ee8987de82fd25cc62abc86e2b" ++
hex"577fc55175be138680df7253a8bcae9d9954391d3bed806ce5a6869b4553" ++
hex"0f214486b1b7f0347efcfde58ca0882f059f7b1541c74506930897c78e23" ++
hex"a6c94b49856369606ed652b8c7402a49f289cb5d1098bb999112225327e0" ++
hex"a32efd2bcd192a2ffbd1997c6a3b7d1a9445bc31fb57485ebe0c431e482b" ++
hex"04e509e557cff107cee08a45c22aa3cbdcb9d305bd95c919e90239e0ec29" ++
hex"2a5418a6151f431e8ab82278b3d816ecd483f43d3d657dae9996cc523fdd" ++
hex"242c4e01935db91a2936e9398ff7278b8a3430eed99ad25fc2a41afc0b4a" ++
hex"e417f6c1785414607cfa13f04173740333a5b58655c74a51deddb38cf8c3" ++
hex"d50b7d2ccf380cad34a5c341e7155494cc4560dff3b19bf88b4d73e9ce76" ++
hex"cbeff573fe93674e4a752d06d5321ff00a4582d62683fb4986d36eaec825" ++
hex"c14d41b2d5aefaf539e989f7fa097eac657c70b975c56e26b73fb9401ce3" ++
hex"81502f0883d52c6a3bcc956e0ea1787f0717d0205fecfe55b01edb1ac0"
Vector(
FilterResponse(compactFilter = BlockFilter
.fromBytes(filterBytes, testBlockHash.flip),
blockHash = testBlockHash,
blockHeight = 1))
}
override def epochSecondToBlockHeight(time: Long): Future[Int] =
Future.successful(0)
/** calculates the median time passed */
override def getMedianTimePast(): Future[Long] =
Future.successful(0L)
}

View File

@ -38,12 +38,12 @@ trait BitcoinSDLCNodeTest extends BitcoinSWalletTest with CachedTor {
nodeApi,
chainQueryApi,
getBIP39PasswordOpt(),
Some(segwitWalletConf))(configA, system)
Some(BaseWalletTest.segwitWalletConf))(configA, system)
walletB <- FundWalletUtil.createFundedDLCWallet(
nodeApi,
chainQueryApi,
getBIP39PasswordOpt(),
Some(segwitWalletConf))(configB, system)
Some(BaseWalletTest.segwitWalletConf))(configB, system)
nodeA = configA.dlcNodeConf.createDLCNode(walletA.wallet)
nodeB = configB.dlcNodeConf.createDLCNode(walletB.wallet)

View File

@ -6,7 +6,7 @@ import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
import org.bitcoins.testkit.util.BitcoinSAsyncFixtureTest
import org.scalatest._
import scala.concurrent.{Future, Promise}
import scala.concurrent.{ExecutionContext, Future, Promise}
import scala.util.{Failure, Success}
object UsesExperimentalBitcoind extends Tag("UsesExperimentalBitcoind")
@ -78,64 +78,6 @@ trait BitcoinSFixture extends BitcoinSAsyncFixtureTest {
new FutureOutcome(outcomeAfterDestroyF)
}
/** Given two fixture building methods (one dependent on the other), returns a single
* fixture building method where the fixture is the pair of the two.
*
* Example:
* {{{
* composeBuilders(createBlockHeaderDAO, createChainHandlerFromBlockHeaderDAO)
* }}}
*/
def composeBuilders[T, U](
builder: () => Future[T],
dependentBuilder: T => Future[U]): () => Future[(T, U)] =
() => {
builder().flatMap { first =>
dependentBuilder(first).map { second =>
(first, second)
}
}
}
/** Given two fixture building methods (one dependent on the other) and a wrapper
* for their pair type, returns a single fixture building method where the fixture is wrapper.
*
* Example:
* {{{
* composeBuildersAndWrap(
* createBitcoind,
* createChainHandlerWithBitcoindZmq,
* BitcoindChainHandler.apply)
* }}}
*/
def composeBuildersAndWrap[T, U, C](
builder: () => Future[T],
dependentBuilder: T => Future[U],
wrap: (T, U) => C): () => Future[C] =
() => {
composeBuilders(builder, dependentBuilder)().map { case (first, second) =>
wrap(first, second)
}
}
/** Given two fixture building methods (one dependent on the other) and
* a function that processes the result of the builders returning a Future,
* returns a single fixture building method where the fixture is wrapper.
*
* This method is identical to `composeBuildersAndWrap`, except that
* the wrapping function returns a `Future[C]` instead of a `C`
*/
def composeBuildersAndWrapFuture[T, U, C](
builder: () => Future[T],
dependentBuilder: T => Future[U],
processResult: (T, U) => Future[C]
): () => Future[C] =
() => {
composeBuilders(builder, dependentBuilder)().flatMap {
case (first, second) => processResult(first, second)
}
}
override def afterAll(): Unit = {
super[BitcoinSAsyncFixtureTest].afterAll()
}
@ -164,4 +106,65 @@ object BitcoinSFixture {
}
BitcoindRpcTestUtil.startServers(Vector(bitcoind)).map(_ => bitcoind)
}
/** Given two fixture building methods (one dependent on the other), returns a single
* fixture building method where the fixture is the pair of the two.
*
* Example:
* {{{
* composeBuilders(createBlockHeaderDAO, createChainHandlerFromBlockHeaderDAO)
* }}}
*/
def composeBuilders[T, U](
builder: () => Future[T],
dependentBuilder: T => Future[U])(implicit
ec: ExecutionContext): () => Future[(T, U)] =
() => {
builder().flatMap { first =>
dependentBuilder(first).map { second =>
(first, second)
}
}
}
/** Given two fixture building methods (one dependent on the other) and a wrapper
* for their pair type, returns a single fixture building method where the fixture is wrapper.
*
* Example:
* {{{
* composeBuildersAndWrap(
* createBitcoind,
* createChainHandlerWithBitcoindZmq,
* BitcoindChainHandler.apply)
* }}}
*/
def composeBuildersAndWrap[T, U, C](
builder: () => Future[T],
dependentBuilder: T => Future[U],
wrap: (T, U) => C)(implicit ec: ExecutionContext): () => Future[C] =
() => {
composeBuilders(builder, dependentBuilder)(ec)().map {
case (first, second) =>
wrap(first, second)
}
}
/** Given two fixture building methods (one dependent on the other) and
* a function that processes the result of the builders returning a Future,
* returns a single fixture building method where the fixture is wrapper.
*
* This method is identical to `composeBuildersAndWrap`, except that
* the wrapping function returns a `Future[C]` instead of a `C`
*/
def composeBuildersAndWrapFuture[T, U, C](
builder: () => Future[T],
dependentBuilder: T => Future[U],
processResult: (T, U) => Future[C]
)(implicit ec: ExecutionContext): () => Future[C] =
() => {
composeBuilders(builder, dependentBuilder)(ec)().flatMap {
case (first, second) => processResult(first, second)
}
}
}

View File

@ -0,0 +1,19 @@
package org.bitcoins.testkit.node
import org.bitcoins.core.api.node.NodeApi
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.crypto.DoubleSha256Digest
import scala.concurrent.Future
object MockNodeApi extends NodeApi {
val mock: NodeApi = this
override def broadcastTransactions(
transactions: Vector[Transaction]): Future[Unit] =
Future.unit
override def downloadBlocks(
blockHashes: Vector[DoubleSha256Digest]): Future[Unit] = Future.unit
}

View File

@ -4,21 +4,14 @@ import akka.actor.ActorSystem
import com.typesafe.config.{Config, ConfigFactory}
import org.bitcoins.commons.config.AppConfig
import org.bitcoins.core.api.chain.ChainQueryApi
import org.bitcoins.core.api.chain.ChainQueryApi.FilterResponse
import org.bitcoins.core.gcs.BlockFilter
import org.bitcoins.core.protocol.BlockStamp
import org.bitcoins.core.protocol.blockchain.RegTestNetChainParams
import org.bitcoins.core.util.FutureUtil
import org.bitcoins.crypto.DoubleSha256DigestBE
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.chain.MockChainQueryApi
import org.bitcoins.testkit.keymanager.KeyManagerTestUtil
import org.bitcoins.testkit.util.BitcoinSAkkaAsyncTest
import org.bitcoins.testkit.{BitcoinSTestAppConfig, EmbeddedPg}
import org.bitcoins.wallet.config.WalletAppConfig
import org.scalatest.Suite
import scala.concurrent.Future
/** Base test trait for all the tests in our walletTest module */
trait BaseWalletTest extends EmbeddedPg { _: Suite with BitcoinSAkkaAsyncTest =>
@ -31,16 +24,6 @@ trait BaseWalletTest extends EmbeddedPg { _: Suite with BitcoinSAkkaAsyncTest =>
super[EmbeddedPg].afterAll()
}
val legacyWalletConf: Config =
ConfigFactory.parseString("bitcoin-s.wallet.defaultAccountType = legacy")
val segwitWalletConf: Config =
ConfigFactory.parseString("bitcoin-s.wallet.defaultAccountType = segwit")
// This is a random block on testnet
val testBlockHash: DoubleSha256DigestBE = DoubleSha256DigestBE.fromHex(
"00000000496dcc754fabd97f3e2df0a7337eab417d75537fecf97a7ebb0e7c75")
/** Wallet config with data directory set to user temp directory */
protected def getFreshConfig: BitcoinSAppConfig =
BaseWalletTest.getFreshConfig(pgUrl, Vector.empty)
@ -52,88 +35,7 @@ trait BaseWalletTest extends EmbeddedPg { _: Suite with BitcoinSAkkaAsyncTest =>
def getBIP39PasswordOpt(): Option[String] =
KeyManagerTestUtil.bip39PasswordOpt
def chainQueryApi: ChainQueryApi =
new ChainQueryApi {
/** Gets the height of the given block */
override def getBlockHeight(
blockHash: DoubleSha256DigestBE): Future[Option[Int]] = {
if (blockHash == testBlockHash) {
Future.successful(Some(1))
} else if (
blockHash == RegTestNetChainParams.genesisBlock.blockHeader.hashBE
) {
Future.successful(Some(1))
} else FutureUtil.none
}
/** Gets the hash of the block that is what we consider "best" */
override def getBestBlockHash(): Future[DoubleSha256DigestBE] =
Future.successful(testBlockHash)
/** Gets number of confirmations for the given block hash */
override def getNumberOfConfirmations(
blockHash: DoubleSha256DigestBE): Future[Option[Int]] = {
if (blockHash == testBlockHash) {
Future.successful(Some(6))
} else FutureUtil.none
}
/** Gets the number of compact filters in the database */
override def getFilterCount(): Future[Int] = Future.successful(1)
/** Returns the block height of the given block stamp */
override def getHeightByBlockStamp(blockStamp: BlockStamp): Future[Int] =
Future.successful(1)
override def getFiltersBetweenHeights(
startHeight: Int,
endHeight: Int): Future[Vector[FilterResponse]] =
Future.successful {
import scodec.bits._
// This is a filter for the random block on testnet
val filterBytes: ByteVector =
hex"fd2701f0ed169ad16107a8a74609b9e4de3c6133c564f79923ca228805d3" ++
hex"8e3efc796c4b35034cb573b10b759cdda5efd19e1cdb4d343afcb06455fa" ++
hex"820b06eca828ad61d3377fa464f3bd06ff4432310a363f667e13d09ba993" ++
hex"264c703a0aa668b33eaa555bd3e93ac85dfde380ab723aafd407dfa13ffe" ++
hex"2e7ddf6f452bd0d977617c4ab2dc3b38c26810023984ad57890e3cf34cfc" ++
hex"2d4a6973b9430ede26bfd9f5bb24e043d48483d84b9025d0a940b15f13fc" ++
hex"0a1e77abd7626869f417c7710e9a6315477691d7c4e2c50f0e776755a62a" ++
hex"b6f0e8eb7a3be8d1a8c3d9dd4602efc5146f0d431d1669378d7afa03c7b9" ++
hex"84d9b0b78007abb6e7c036156e5186d1d79a2f37daecfcbe8821cf42851c" ++
hex"b10ef0c359307d54e53078eb631f02c067a474dceb484da20bc0e7c5451a" ++
hex"b957f46b306caa82938b19bb34fd76c5cc07e048932524704dec8f72c91c" ++
hex"d5ee1f4648de839047a0bea0d4d4d66c19cfccc2b5f285a84af18114f608" ++
hex"f144391648aedfb5ffcccbb51272512d6ba9a2e19a47cebe5b50a8a7073a" ++
hex"1c24059440444047a41bdbab16f61bc4b0ee8987de82fd25cc62abc86e2b" ++
hex"577fc55175be138680df7253a8bcae9d9954391d3bed806ce5a6869b4553" ++
hex"0f214486b1b7f0347efcfde58ca0882f059f7b1541c74506930897c78e23" ++
hex"a6c94b49856369606ed652b8c7402a49f289cb5d1098bb999112225327e0" ++
hex"a32efd2bcd192a2ffbd1997c6a3b7d1a9445bc31fb57485ebe0c431e482b" ++
hex"04e509e557cff107cee08a45c22aa3cbdcb9d305bd95c919e90239e0ec29" ++
hex"2a5418a6151f431e8ab82278b3d816ecd483f43d3d657dae9996cc523fdd" ++
hex"242c4e01935db91a2936e9398ff7278b8a3430eed99ad25fc2a41afc0b4a" ++
hex"e417f6c1785414607cfa13f04173740333a5b58655c74a51deddb38cf8c3" ++
hex"d50b7d2ccf380cad34a5c341e7155494cc4560dff3b19bf88b4d73e9ce76" ++
hex"cbeff573fe93674e4a752d06d5321ff00a4582d62683fb4986d36eaec825" ++
hex"c14d41b2d5aefaf539e989f7fa097eac657c70b975c56e26b73fb9401ce3" ++
hex"81502f0883d52c6a3bcc956e0ea1787f0717d0205fecfe55b01edb1ac0"
Vector(
FilterResponse(compactFilter = BlockFilter
.fromBytes(filterBytes, testBlockHash.flip),
blockHash = testBlockHash,
blockHeight = 1))
}
override def epochSecondToBlockHeight(time: Long): Future[Int] =
Future.successful(0)
/** calculates the median time passed */
override def getMedianTimePast(): Future[Long] =
Future.successful(0L)
}
def chainQueryApi: ChainQueryApi = MockChainQueryApi
}
@ -150,4 +52,10 @@ object BaseWalletTest {
getFreshConfig(pgUrl, config).walletConf
}
val legacyWalletConf: Config =
ConfigFactory.parseString("bitcoin-s.wallet.defaultAccountType = legacy")
val segwitWalletConf: Config =
ConfigFactory.parseString("bitcoin-s.wallet.defaultAccountType = segwit")
}

View File

@ -48,15 +48,16 @@ trait BitcoinSDualWalletTest extends BitcoinSWalletTest {
build = () =>
for {
walletA <-
FundWalletUtil.createFundedDLCWallet(nodeApi,
chainQueryApi,
getBIP39PasswordOpt(),
Some(segwitWalletConf))
FundWalletUtil.createFundedDLCWallet(
nodeApi,
chainQueryApi,
getBIP39PasswordOpt(),
Some(BaseWalletTest.segwitWalletConf))
walletB <- FundWalletUtil.createFundedDLCWallet(
nodeApi,
chainQueryApi,
getBIP39PasswordOpt(),
Some(segwitWalletConf))(config2, system)
Some(BaseWalletTest.segwitWalletConf))(config2, system)
} yield (walletA, walletB),
destroy = { fundedWallets: (FundedDLCWallet, FundedDLCWallet) =>
for {
@ -90,12 +91,12 @@ trait BitcoinSDualWalletTest extends BitcoinSWalletTest {
nodeApi = nodeApi,
chainQueryApi = chainQueryApi,
bip39PasswordOpt = getBIP39PasswordOpt(),
extraConfig = Some(segwitWalletConf))
extraConfig = Some(BaseWalletTest.segwitWalletConf))
val walletBF = FundWalletUtil.createFundedDLCWallet(
nodeApi,
chainQueryApi,
getBIP39PasswordOpt(),
Some(segwitWalletConf))(config2, system)
Some(BaseWalletTest.segwitWalletConf))(config2, system)
for {
walletA <- walletAF
walletB <- walletBF
@ -154,11 +155,11 @@ trait BitcoinSDualWalletTest extends BitcoinSWalletTest {
walletA <- FundWalletUtil.createFundedDLCWalletWithBitcoind(
bitcoind,
getBIP39PasswordOpt(),
Some(segwitWalletConf))
Some(BaseWalletTest.segwitWalletConf))
walletB <- FundWalletUtil.createFundedDLCWalletWithBitcoind(
bitcoind = bitcoind,
bip39PasswordOpt = getBIP39PasswordOpt(),
extraConfig = Some(segwitWalletConf))(config2, system)
extraConfig = Some(BaseWalletTest.segwitWalletConf))(config2, system)
amt = expectedDefaultAmt / Satoshis(2)
contractInfo = SingleContractInfo(amt.satoshis, contractOraclePair)
(dlcWalletA, dlcWalletB) <-
@ -176,12 +177,12 @@ trait BitcoinSDualWalletTest extends BitcoinSWalletTest {
nodeApi = nodeApi,
chainQueryApi = chainQueryApi,
bip39PasswordOpt = getBIP39PasswordOpt(),
extraConfig = Some(segwitWalletConf))
extraConfig = Some(BaseWalletTest.segwitWalletConf))
walletB <- FundWalletUtil.createFundedDLCWallet(
nodeApi = nodeApi,
chainQueryApi = chainQueryApi,
bip39PasswordOpt = getBIP39PasswordOpt(),
extraConfig = Some(segwitWalletConf))(config2, system)
extraConfig = Some(BaseWalletTest.segwitWalletConf))(config2, system)
amt = expectedDefaultAmt / Satoshis(2)
contractInfo = SingleContractInfo(amt.satoshis, contractOraclePair)
(dlcWalletA, dlcWalletB) <-

View File

@ -5,15 +5,10 @@ import com.typesafe.config.{Config, ConfigFactory}
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.commons.config.AppConfig
import org.bitcoins.core.api.chain.ChainQueryApi
import org.bitcoins.core.api.chain.ChainQueryApi.FilterResponse
import org.bitcoins.core.api.feeprovider.FeeRateApi
import org.bitcoins.core.api.node.NodeApi
import org.bitcoins.core.currency._
import org.bitcoins.core.protocol.BlockStamp
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.core.util.FutureUtil
import org.bitcoins.core.wallet.fee._
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
import org.bitcoins.dlc.wallet.{DLCAppConfig, DLCWallet}
import org.bitcoins.node.NodeCallbacks
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
@ -24,6 +19,7 @@ import org.bitcoins.testkit.EmbeddedPg
import org.bitcoins.testkit.chain.SyncUtil
import org.bitcoins.testkit.fixtures.BitcoinSFixture
import org.bitcoins.testkit.keymanager.KeyManagerTestUtil
import org.bitcoins.testkit.node.MockNodeApi
import org.bitcoins.testkit.wallet.FundWalletUtil.{
FundedDLCWallet,
FundedWallet
@ -102,10 +98,11 @@ trait BitcoinSWalletTest
walletAppConfig: WalletAppConfig): FutureOutcome = {
makeDependentFixture(
build = () =>
FundWalletUtil.createFundedWallet(nodeApi,
chainQueryApi,
bip39PasswordOpt,
Some(segwitWalletConf)),
FundWalletUtil.createFundedWallet(
nodeApi,
chainQueryApi,
bip39PasswordOpt,
Some(BaseWalletTest.segwitWalletConf)),
destroy = { funded: FundedWallet =>
destroyWallet(funded.wallet)
}
@ -135,12 +132,12 @@ trait BitcoinSWalletTest
/** Fixture for an initialized wallet which produce legacy addresses */
def withLegacyWallet(test: OneArgAsyncTest): FutureOutcome = {
withNewConfiguredWallet(legacyWalletConf)(test)
withNewConfiguredWallet(BaseWalletTest.legacyWalletConf)(test)
}
/** Fixture for an initialized wallet which produce segwit addresses */
def withSegwitWallet(test: OneArgAsyncTest): FutureOutcome = {
withNewConfiguredWallet(segwitWalletConf)(test)
withNewConfiguredWallet(BaseWalletTest.segwitWalletConf)(test)
}
/** Fixture for a wallet with default configuration with no funds in it */
@ -165,39 +162,46 @@ trait BitcoinSWalletTest
def withNewWalletAndBitcoind(test: OneArgAsyncTest)(implicit
walletAppConfig: WalletAppConfig): FutureOutcome = {
val builder: () => Future[WalletWithBitcoind] = composeBuildersAndWrap(
builder = { () =>
BitcoinSFixture.createBitcoindWithFunds(Some(BitcoindVersion.newest))
},
dependentBuilder = { (bitcoind: BitcoindRpcClient) =>
createWalletWithBitcoind(bitcoind)
},
wrap = (_: BitcoindRpcClient, walletWithBitcoind: WalletWithBitcoind) =>
walletWithBitcoind
)
val builder: () => Future[WalletWithBitcoindRpc] =
BitcoinSFixture.composeBuildersAndWrap(
builder = { () =>
BitcoinSFixture.createBitcoindWithFunds(Some(BitcoindVersion.newest))
},
dependentBuilder = { (bitcoind: BitcoindRpcClient) =>
createWalletWithBitcoind(bitcoind)
},
wrap =
(_: BitcoindRpcClient, walletWithBitcoind: WalletWithBitcoindRpc) =>
walletWithBitcoind
)
makeDependentFixture(builder, destroy = destroyWalletWithBitcoind)(test)
makeDependentFixture(
builder,
destroy = destroyWalletWithBitcoind(_: WalletWithBitcoindRpc))(test)
}
def withNewWalletAndBitcoindV19(
test: OneArgAsyncTest,
bip39PasswordOpt: Option[String])(implicit
walletAppConfig: WalletAppConfig): FutureOutcome = {
val builder: () => Future[WalletWithBitcoind] = composeBuildersAndWrap(
builder = { () =>
BitcoinSFixture
.createBitcoindWithFunds(Some(BitcoindVersion.V19))
.map(_.asInstanceOf[BitcoindV19RpcClient])
},
dependentBuilder = { (bitcoind: BitcoindV19RpcClient) =>
createWalletWithBitcoindV19(bitcoind, bip39PasswordOpt)
},
wrap =
(_: BitcoindV19RpcClient, walletWithBitcoind: WalletWithBitcoindV19) =>
walletWithBitcoind
)
val builder: () => Future[WalletWithBitcoindV19] =
BitcoinSFixture.composeBuildersAndWrap(
builder = { () =>
BitcoinSFixture
.createBitcoindWithFunds(Some(BitcoindVersion.V19))
.map(_.asInstanceOf[BitcoindV19RpcClient])
},
dependentBuilder = { (bitcoind: BitcoindV19RpcClient) =>
createWalletWithBitcoindV19(bitcoind, bip39PasswordOpt)
},
wrap = (
_: BitcoindV19RpcClient,
walletWithBitcoind: WalletWithBitcoindV19) => walletWithBitcoind
)
makeDependentFixture(builder, destroy = destroyWalletWithBitcoind)(test)
makeDependentFixture(
builder,
destroy = destroyWalletWithBitcoind(_: WalletWithBitcoindV19))(test)
}
def withFundedWalletAndBitcoindV19(
@ -220,7 +224,9 @@ trait BitcoinSWalletTest
}
}
makeDependentFixture(builder, destroy = destroyWalletWithBitcoind)(test)
makeDependentFixture(
builder,
destroy = destroyWalletWithBitcoind(_: WalletWithBitcoindV19))(test)
}
def withWalletConfig(test: OneArgAsyncTest): FutureOutcome = {
@ -261,48 +267,6 @@ object BitcoinSWalletTest extends WalletLogger {
lazy val initialFunds: CurrencyUnit = expectedDefaultAmt + expectedAccount1Amt
object MockNodeApi extends NodeApi {
override def broadcastTransactions(
transactions: Vector[Transaction]): Future[Unit] =
Future.unit
override def downloadBlocks(
blockHashes: Vector[DoubleSha256Digest]): Future[Unit] = Future.unit
}
object MockChainQueryApi extends ChainQueryApi {
override def getBlockHeight(
blockHash: DoubleSha256DigestBE): Future[Option[Int]] =
FutureUtil.none
override def getBestBlockHash(): Future[DoubleSha256DigestBE] =
Future.successful(DoubleSha256DigestBE.empty)
override def getNumberOfConfirmations(
blockHashOpt: DoubleSha256DigestBE): Future[Option[Int]] =
FutureUtil.none
override def getHeightByBlockStamp(blockStamp: BlockStamp): Future[Int] =
Future.successful(0)
override def getFilterCount(): Future[Int] = Future.successful(0)
override def getFiltersBetweenHeights(
startHeight: Int,
endHeight: Int): Future[Vector[FilterResponse]] =
Future.successful(Vector.empty)
override def epochSecondToBlockHeight(time: Long): Future[Int] =
Future.successful(0)
/** calculates the median time passed */
override def getMedianTimePast(): Future[Long] =
Future.successful(0L)
}
private[bitcoins] class RandomFeeProvider extends FeeRateApi {
// Useful for tests
var lastFeeRate: Option[FeeUnit] = None
@ -463,7 +427,7 @@ object BitcoinSWalletTest extends WalletLogger {
bip39PasswordOpt: Option[String],
extraConfig: Option[Config] = None)(implicit
config: WalletAppConfig,
system: ActorSystem): Future[WalletWithBitcoind] = {
system: ActorSystem): Future[WalletWithBitcoindRpc] = {
import system.dispatcher
//we need to create a promise so we can inject the wallet with the callback
//after we have created it into SyncUtil.getNodeApiWalletCallback
@ -537,7 +501,7 @@ object BitcoinSWalletTest extends WalletLogger {
/** Pairs the given wallet with a bitcoind instance that has money in the bitcoind wallet */
def createWalletWithBitcoind(
wallet: Wallet
)(implicit system: ActorSystem): Future[WalletWithBitcoind] = {
)(implicit system: ActorSystem): Future[WalletWithBitcoindRpc] = {
val bitcoindF = BitcoinSFixture.createBitcoindWithFunds()
bitcoindF.map(WalletWithBitcoindRpc(wallet, _))(system.dispatcher)
}
@ -546,7 +510,7 @@ object BitcoinSWalletTest extends WalletLogger {
def createWalletWithBitcoind(
wallet: Wallet,
versionOpt: Option[BitcoindVersion]
)(implicit system: ActorSystem): Future[WalletWithBitcoind] = {
)(implicit system: ActorSystem): Future[WalletWithBitcoindRpc] = {
import system.dispatcher
val bitcoindF = BitcoinSFixture.createBitcoindWithFunds(versionOpt)
bitcoindF.map(WalletWithBitcoindRpc(wallet, _))
@ -554,7 +518,7 @@ object BitcoinSWalletTest extends WalletLogger {
def createWalletWithBitcoind(bitcoind: BitcoindRpcClient)(implicit
system: ActorSystem,
config: WalletAppConfig): Future[WalletWithBitcoind] = {
config: WalletAppConfig): Future[WalletWithBitcoindRpc] = {
createWalletWithBitcoindCallbacks(bitcoind, None)
}
@ -595,7 +559,7 @@ object BitcoinSWalletTest extends WalletLogger {
def createWalletWithBitcoind(
wallet: Wallet,
bitcoindRpcClient: BitcoindRpcClient
): Future[WalletWithBitcoind] = {
): Future[WalletWithBitcoindRpc] = {
Future.successful(WalletWithBitcoindRpc(wallet, bitcoindRpcClient))
}
@ -607,7 +571,7 @@ object BitcoinSWalletTest extends WalletLogger {
chainQueryApi: ChainQueryApi,
walletCallbacks: WalletCallbacks)(implicit
config: BitcoinSAppConfig,
system: ActorSystem): Future[WalletWithBitcoind] = {
system: ActorSystem): Future[WalletWithBitcoindRpc] = {
import system.dispatcher
config.walletConf.addCallbacks(walletCallbacks)
for {
@ -620,7 +584,7 @@ object BitcoinSWalletTest extends WalletLogger {
} yield funded
}
/** Funds a wallet with bitcoind, this method adds [[BitcoinSWalletTest.createNodeCallbacksForWallet()]]
/** Funds a wallet with bitcoind, this method adds [[CallbackUtil.createNeutrinoNodeCallbacksForWallet()]]
* which processes filters/blocks that can be used to fund the wallet.
*
* It's important to note that this does NOT synchronize the wallet with a chain state.
@ -634,7 +598,7 @@ object BitcoinSWalletTest extends WalletLogger {
bip39PasswordOpt: Option[String],
walletCallbacks: WalletCallbacks)(implicit
config: BitcoinSAppConfig,
system: ActorSystem): Future[WalletWithBitcoind] = {
system: ActorSystem): Future[WalletWithBitcoindRpc] = {
import system.dispatcher
config.walletConf.addCallbacks(walletCallbacks)
for {
@ -651,7 +615,8 @@ object BitcoinSWalletTest extends WalletLogger {
} yield funded
}
def destroyWalletWithBitcoind(walletWithBitcoind: WalletWithBitcoind)(implicit
def destroyWalletWithBitcoind[T <: BitcoindRpcClient](
walletWithBitcoind: WalletWithBitcoind[T])(implicit
ec: ExecutionContext): Future[Unit] = {
val (wallet, bitcoind) =
(walletWithBitcoind.wallet, walletWithBitcoind.bitcoind)
@ -697,7 +662,7 @@ object BitcoinSWalletTest extends WalletLogger {
/** Makes sure our wallet is fully funded with the default amounts specified in
* [[BitcoinSWalletTest]]. This will future won't be completed until balances satisfy [[isSameWalletBalances()]]
*/
def awaitWalletBalances(fundedWallet: WalletWithBitcoind)(implicit
def awaitWalletBalances(fundedWallet: WalletWithBitcoind[_])(implicit
config: WalletAppConfig,
system: ActorSystem): Future[Unit] = {
AsyncUtil.retryUntilSatisfiedF(conditionF =
@ -706,7 +671,7 @@ object BitcoinSWalletTest extends WalletLogger {
maxTries = 100)(system.dispatcher)
}
private def isSameWalletBalances(fundedWallet: WalletWithBitcoind)(implicit
private def isSameWalletBalances(fundedWallet: WalletWithBitcoind[_])(implicit
config: WalletAppConfig,
system: ActorSystem): Future[Boolean] = {
import system.dispatcher

View File

@ -44,7 +44,7 @@ trait BitcoinSWalletTestCachedBitcoind
bip39PasswordOpt: Option[String],
bitcoind: BitcoindRpcClient)(implicit
walletAppConfig: WalletAppConfig): FutureOutcome = {
val builder: () => Future[WalletWithBitcoind] = { () =>
val builder: () => Future[WalletWithBitcoind[_]] = { () =>
for {
walletWithBitcoind <- createWalletWithBitcoindCallbacks(
bitcoind = bitcoind,
@ -57,9 +57,9 @@ trait BitcoinSWalletTestCachedBitcoind
} yield fundedWallet
}
makeDependentFixture[WalletWithBitcoind](
makeDependentFixture[WalletWithBitcoind[_]](
builder,
{ case walletWithBitcoind: WalletWithBitcoind =>
{ case walletWithBitcoind: WalletWithBitcoind[_] =>
destroyWallet(walletWithBitcoind.wallet)
})(test)
}
@ -69,20 +69,22 @@ trait BitcoinSWalletTestCachedBitcoind
bip39PasswordOpt: Option[String],
bitcoind: BitcoindRpcClient)(implicit
walletAppConfig: WalletAppConfig): FutureOutcome = {
val builder: () => Future[WalletWithBitcoind] = composeBuildersAndWrap(
builder = { () =>
Future.successful(bitcoind)
},
dependentBuilder = { (bitcoind: BitcoindRpcClient) =>
createWalletWithBitcoind(bitcoind, bip39PasswordOpt)
},
wrap = (_: BitcoindRpcClient, walletWithBitcoind: WalletWithBitcoind) =>
walletWithBitcoind
)
val builder: () => Future[WalletWithBitcoind[_]] =
BitcoinSFixture.composeBuildersAndWrap(
builder = { () =>
Future.successful(bitcoind)
},
dependentBuilder = { (bitcoind: BitcoindRpcClient) =>
createWalletWithBitcoind(bitcoind, bip39PasswordOpt)
},
wrap =
(_: BitcoindRpcClient, walletWithBitcoind: WalletWithBitcoind[_]) =>
walletWithBitcoind
)
makeDependentFixture[WalletWithBitcoind](
makeDependentFixture[WalletWithBitcoind[_]](
builder,
{ case walletWithBitcoind: WalletWithBitcoind =>
{ case walletWithBitcoind: WalletWithBitcoind[_] =>
destroyWallet(walletWithBitcoind.wallet)
})(test)
}
@ -183,16 +185,16 @@ trait BitcoinSWalletTestCachedBitcoinV19
walletWithBitcoindV19 = WalletWithBitcoindV19(walletWithBitcoind.wallet,
bitcoind)
fundedWallet <- FundWalletUtil
.fundWalletWithBitcoind[WalletWithBitcoindV19](walletWithBitcoindV19)
.fundWalletWithBitcoind(walletWithBitcoindV19)
_ <- SyncUtil.syncWalletFullBlocks(wallet = fundedWallet.wallet,
bitcoind = bitcoind)
_ <- BitcoinSWalletTest.awaitWalletBalances(fundedWallet)
} yield fundedWallet
}
makeDependentFixture[WalletWithBitcoind](
makeDependentFixture[WalletWithBitcoind[_]](
builder,
destroy = { case walletWithBitcoind: WalletWithBitcoind =>
destroy = { case walletWithBitcoind: WalletWithBitcoind[_] =>
destroyWallet(walletWithBitcoind.wallet)
})(test)
}
@ -202,22 +204,23 @@ trait BitcoinSWalletTestCachedBitcoinV19
bip39PasswordOpt: Option[String],
bitcoind: BitcoindV19RpcClient)(implicit
walletAppConfig: WalletAppConfig): FutureOutcome = {
val builder: () => Future[WalletWithBitcoind] = composeBuildersAndWrap(
builder = { () =>
Future.successful(bitcoind)
},
dependentBuilder = { (bitcoind: BitcoindV19RpcClient) =>
BitcoinSWalletTest.createWalletWithBitcoindV19(bitcoind,
bip39PasswordOpt)
},
wrap =
(_: BitcoindRpcClient, walletWithBitcoind: WalletWithBitcoindV19) =>
walletWithBitcoind
)
val builder: () => Future[WalletWithBitcoind[_]] =
BitcoinSFixture.composeBuildersAndWrap(
builder = { () =>
Future.successful(bitcoind)
},
dependentBuilder = { (bitcoind: BitcoindV19RpcClient) =>
BitcoinSWalletTest.createWalletWithBitcoindV19(bitcoind,
bip39PasswordOpt)
},
wrap =
(_: BitcoindRpcClient, walletWithBitcoind: WalletWithBitcoindV19) =>
walletWithBitcoind
)
makeDependentFixture[WalletWithBitcoind](
makeDependentFixture[WalletWithBitcoind[_]](
builder,
{ case walletWithBitcoind: WalletWithBitcoind =>
{ case walletWithBitcoind: WalletWithBitcoind[_] =>
destroyWallet(walletWithBitcoind.wallet)
})(test)
}

View File

@ -50,11 +50,11 @@ trait DualWalletTestCachedBitcoind
FundWalletUtil.createFundedDLCWalletWithBitcoind(
bitcoind,
getBIP39PasswordOpt(),
Some(segwitWalletConf))
Some(BaseWalletTest.segwitWalletConf))
walletB <- FundWalletUtil.createFundedDLCWalletWithBitcoind(
bitcoind,
getBIP39PasswordOpt(),
Some(segwitWalletConf))(config2, system)
Some(BaseWalletTest.segwitWalletConf))(config2, system)
} yield (walletA, walletB, bitcoind),
destroy = { fundedWallets: (FundedDLCWallet, FundedDLCWallet, _) =>
for {
@ -77,7 +77,7 @@ trait DualWalletTestCachedBitcoind
FundWalletUtil.createFundedDLCWalletWithBitcoind(
bitcoind,
getBIP39PasswordOpt(),
Some(segwitWalletConf))
Some(BaseWalletTest.segwitWalletConf))
}
val walletBF = for {
bitcoind <- bitcoindF
@ -88,7 +88,7 @@ trait DualWalletTestCachedBitcoind
walletB <- FundWalletUtil.createFundedDLCWalletWithBitcoind(
bitcoind,
getBIP39PasswordOpt(),
Some(segwitWalletConf))(config2, system)
Some(BaseWalletTest.segwitWalletConf))(config2, system)
} yield { walletB }
for {

View File

@ -30,8 +30,8 @@ import scala.concurrent.{ExecutionContext, Future}
trait FundWalletUtil extends Logging {
/** Funds the given wallet with money from the given bitcoind */
def fundWalletWithBitcoind[T <: WalletWithBitcoind](pair: T)(implicit
ec: ExecutionContext): Future[T] = {
def fundWalletWithBitcoind[T <: WalletWithBitcoind[_ <: BitcoindRpcClient]](
pair: T)(implicit ec: ExecutionContext): Future[T] = {
val (wallet, bitcoind) = (pair.wallet, pair.bitcoind)
val defaultAccount = wallet.walletConfig.defaultAccount

View File

@ -4,13 +4,16 @@ import org.bitcoins.rpc.client.common.BitcoindRpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
import org.bitcoins.wallet.Wallet
sealed trait WalletWithBitcoind {
sealed trait WalletWithBitcoind[T <: BitcoindRpcClient] {
def wallet: Wallet
def bitcoind: BitcoindRpcClient
def bitcoind: T
}
/** General pairing of a wallet with a bitcoind rpc. If you don't care about
* the version of bitcoind, you should use this.
*/
case class WalletWithBitcoindRpc(wallet: Wallet, bitcoind: BitcoindRpcClient)
extends WalletWithBitcoind
extends WalletWithBitcoind[BitcoindRpcClient]
case class WalletWithBitcoindV19(wallet: Wallet, bitcoind: BitcoindV19RpcClient)
extends WalletWithBitcoind
extends WalletWithBitcoind[BitcoindV19RpcClient]

View File

@ -11,7 +11,6 @@ import org.bitcoins.testkit.util.AkkaUtil
import org.bitcoins.testkit.wallet.{
BitcoinSWalletTest,
WalletTestUtil,
WalletWithBitcoind,
WalletWithBitcoindRpc
}
import org.scalatest.FutureOutcome
@ -20,7 +19,7 @@ import scala.concurrent.duration.DurationInt
class AddressTagIntegrationTest extends BitcoinSWalletTest {
override type FixtureParam = WalletWithBitcoind
override type FixtureParam = WalletWithBitcoindRpc
override def withFixture(test: OneArgAsyncTest): FutureOutcome =
withNewWalletAndBitcoind(test)(getFreshWalletAppConfig)

View File

@ -8,7 +8,7 @@ import org.bitcoins.core.wallet.utxo._
import org.bitcoins.testkit.wallet.{
BitcoinSWalletTestCachedBitcoindNewest,
WalletTestUtil,
WalletWithBitcoind
WalletWithBitcoindRpc
}
import org.bitcoins.testkitcore.util.TestUtil
import org.scalatest.{Assertion, FutureOutcome, Outcome}
@ -18,7 +18,7 @@ import scala.concurrent.Future
class FundTransactionHandlingTest
extends BitcoinSWalletTestCachedBitcoindNewest {
override type FixtureParam = WalletWithBitcoind
override type FixtureParam = WalletWithBitcoindRpc
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
val f: Future[Outcome] = for {
@ -36,7 +36,7 @@ class FundTransactionHandlingTest
TransactionOutput(Bitcoins(0.5), TestUtil.p2pkhScriptPubKey)
it must "fund a simple raw transaction that requires one utxo" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
val wallet = fundedWallet.wallet
for {
feeRate <- wallet.getFeeRate()
@ -55,7 +55,7 @@ class FundTransactionHandlingTest
}
it must "fund a transaction that requires all utxos in our wallet" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
val amt = Bitcoins(5.5)
val newDestination = destination.copy(value = amt)
val wallet = fundedWallet.wallet
@ -76,7 +76,7 @@ class FundTransactionHandlingTest
}
it must "not care about the number of destinations" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
val destinations = Vector.fill(5)(destination)
val wallet = fundedWallet.wallet
@ -99,7 +99,7 @@ class FundTransactionHandlingTest
}
it must "fail to fund a raw transaction if we don't have enough money in our wallet" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
//our wallet should only have 6 bitcoin in it
val tooMuchMoney = Bitcoins(10)
val tooBigOutput = destination.copy(value = tooMuchMoney)
@ -120,7 +120,7 @@ class FundTransactionHandlingTest
}
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: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
//our wallet should only have 6 bitcoin in it
val tooMuchMoney = Bitcoins(6)
val tooBigOutput = destination.copy(value = tooMuchMoney)
@ -141,7 +141,7 @@ class FundTransactionHandlingTest
}
it must "fund from a specific account" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
//we want to fund from account 1, not hte default account
//account 1 has 1 btc in it
val amt = Bitcoins(0.1)
@ -163,7 +163,7 @@ class FundTransactionHandlingTest
}
it must "fail to fund from an account that does not have the funds" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
//account 1 should only have 1 btc in it
val amt = Bitcoins(1.1)
val newDestination = destination.copy(value = amt)
@ -184,7 +184,7 @@ class FundTransactionHandlingTest
}
it must "fail to fund from an account with only immature coinbases" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
val wallet = fundedWallet.wallet
val bitcoind = fundedWallet.bitcoind
val fundedTxF = for {
@ -212,7 +212,7 @@ class FundTransactionHandlingTest
}
it must "mark utxos as reserved after building a transaction" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
val wallet = fundedWallet.wallet
for {
feeRate <- wallet.getFeeRate()
@ -262,7 +262,7 @@ class FundTransactionHandlingTest
}
it must "fund a transaction with only utxos with an unknown address tag" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
val wallet = fundedWallet.wallet
val exampleTag: UnknownAddressTag =
UnknownAddressTag("Example", "ExampleTagType")
@ -271,7 +271,7 @@ class FundTransactionHandlingTest
}
it must "fund a transaction with only utxos with an internal address tag" in {
fundedWallet: WalletWithBitcoind =>
fundedWallet: WalletWithBitcoindRpc =>
val wallet = fundedWallet.wallet
testAddressTagFunding(wallet, HotStorage)

View File

@ -2,10 +2,11 @@ package org.bitcoins.wallet
import com.typesafe.config.ConfigFactory
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.chain.MockChainQueryApi
import org.bitcoins.testkit.keymanager.KeyManagerTestUtil.bip39PasswordOpt
import org.bitcoins.testkit.node.MockNodeApi
import org.bitcoins.testkit.util.BitcoinSAsyncTest
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.bitcoins.testkit.wallet.BitcoinSWalletTest._
import org.bitcoins.testkit.{BitcoinSTestAppConfig, EmbeddedPg}
import org.scalatest.Assertion

View File

@ -9,6 +9,7 @@ import org.bitcoins.core.protocol.transaction.{
TransactionOutput
}
import org.bitcoins.core.wallet.fee.SatoshisPerByte
import org.bitcoins.testkit.chain.MockChainQueryApi
import org.bitcoins.testkit.wallet.{BitcoinSWalletTest, WalletTestUtil}
import org.bitcoins.testkitcore.Implicits._
import org.bitcoins.testkitcore.gen.TransactionGenerators
@ -71,14 +72,15 @@ class ProcessTransactionTest extends BitcoinSWalletTest {
wallet.processTransaction(tx, None)
}
_ <- wallet.processTransaction(tx, Some(testBlockHash))
_ <- wallet.processTransaction(tx,
Some(MockChainQueryApi.testBlockHash))
newConfirmed <- wallet.getConfirmedBalance()
newUnconfirmed <- wallet.getUnconfirmedBalance()
utxosPostAdd <- wallet.listUtxos()
// repeating the action should not make a difference
_ <- checkUtxosAndBalance(wallet) {
wallet.processTransaction(tx, Some(testBlockHash))
wallet.processTransaction(tx, Some(MockChainQueryApi.testBlockHash))
}
} yield {
val ourOutputs =

View File

@ -12,7 +12,6 @@ import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.wallet.{
BitcoinSWalletTestCachedBitcoindNewest,
WalletWithBitcoind,
WalletWithBitcoindRpc
}
@ -25,12 +24,12 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
override protected def getFreshConfig: BitcoinSAppConfig =
BitcoinSTestAppConfig.getNeutrinoWithEmbeddedDbTestConfig(pgUrl)
override type FixtureParam = WalletWithBitcoind
override type FixtureParam = WalletWithBitcoindRpc
behavior of "Wallet rescans"
it must "properly clear utxos but not addresses for an account" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val wallet = fixture.wallet
for {
@ -53,7 +52,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
}
it must "properly clear all utxos and address" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val wallet = fixture.wallet
for {
@ -77,7 +76,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
val DEFAULT_ADDR_BATCH_SIZE = 10
it must "be able to discover funds that belong to the wallet using WalletApi.rescanNeutrinoWallet" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val WalletWithBitcoindRpc(wallet, _) = fixture
val initBalanceF = wallet.getBalance()
@ -99,7 +98,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
}
it must "be able to discover funds that occurred within a certain range" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val WalletWithBitcoindRpc(wallet, bitcoind) = fixture
val amt = Bitcoins.one
@ -160,7 +159,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
}
it must "be able to discover funds using multiple batches" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val WalletWithBitcoindRpc(wallet, bitcoind) = fixture
val amt = Bitcoins.one
@ -223,7 +222,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
}
it must "be able to discover funds that occurred from the wallet creation time" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val WalletWithBitcoindRpc(wallet, bitcoind) = fixture
val amt = Bitcoins.one
@ -275,7 +274,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
}
it must "NOT discover funds that happened OUTSIDE of a certain range of block hashes" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val WalletWithBitcoindRpc(wallet, _) = fixture
val initBalanceF = wallet.getBalance()
@ -322,7 +321,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
}
it must "acknowledge that a rescan is already in progress" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val WalletWithBitcoindRpc(wallet, _) = fixture
//do these in parallel on purpose to simulate multiple threads calling rescan
val startF = wallet.rescanNeutrinoWallet(startOpt = None,
@ -354,7 +353,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
}
it must "still receive payments to addresses generated pre-rescan" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val WalletWithBitcoindRpc(wallet, bitcoind) = fixture
val addressNoFundsF = wallet.getNewAddress()
@ -390,7 +389,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
}
it must "discover funds after rescanning twice" in {
fixture: WalletWithBitcoind =>
fixture: WalletWithBitcoindRpc =>
val WalletWithBitcoindRpc(wallet, bitcoind) = fixture
val amt = Bitcoins.one
for {

View File

@ -10,12 +10,10 @@ import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
import org.bitcoins.core.wallet.keymanagement.KeyManagerParams
import org.bitcoins.feeprovider.ConstantFeeRateProvider
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.chain.MockChainQueryApi
import org.bitcoins.testkit.fixtures.EmptyFixture
import org.bitcoins.testkit.node.MockNodeApi
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.bitcoins.testkit.wallet.BitcoinSWalletTest.{
MockChainQueryApi,
MockNodeApi
}
import org.bitcoins.wallet.config.WalletAppConfig
import org.scalatest.compatible.Assertion
import play.api.libs.json._

View File

@ -16,7 +16,6 @@ import org.bitcoins.core.wallet.utxo.TxoState._
import org.bitcoins.crypto.ECPublicKey
import org.bitcoins.testkit.wallet.{
BitcoinSWalletTestCachedBitcoindNewest,
WalletWithBitcoind,
WalletWithBitcoindRpc
}
import org.scalatest.{FutureOutcome, Outcome}
@ -29,7 +28,7 @@ class UTXOLifeCycleTest
behavior of "Wallet Txo States"
override type FixtureParam = WalletWithBitcoind
override type FixtureParam = WalletWithBitcoindRpc
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
val f: Future[Outcome] = for {

View File

@ -13,7 +13,6 @@ import org.bitcoins.testkit.wallet.BitcoinSWalletTest.RandomFeeProvider
import org.bitcoins.testkit.wallet.{
BitcoinSWalletTestCachedBitcoindNewest,
WalletTestUtil,
WalletWithBitcoind,
WalletWithBitcoindRpc
}
import org.scalatest.{FutureOutcome, Outcome}
@ -22,7 +21,7 @@ import scala.concurrent.Future
class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
override type FixtureParam = WalletWithBitcoind
override type FixtureParam = WalletWithBitcoindRpc
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
val f: Future[Outcome] = for {

View File

@ -9,6 +9,7 @@ import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.script._
import org.bitcoins.core.util.FutureUtil
import org.bitcoins.crypto.{CryptoUtil, ECPublicKey}
import org.bitcoins.testkit.chain.MockChainQueryApi
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.bitcoins.testkitcore.util.TransactionTestUtil._
import org.scalatest.FutureOutcome
@ -140,8 +141,9 @@ class WalletUnitTest extends BitcoinSWalletTest {
)
} yield {
assert(
Vector(BlockMatchingResponse(blockHash = testBlockHash,
blockHeight = 1)) == matched)
Vector(
BlockMatchingResponse(blockHash = MockChainQueryApi.testBlockHash,
blockHeight = 1)) == matched)
}
}