From e1bd6a158bf373e58554bfd5bd6999834cda7dcd Mon Sep 17 00:00:00 2001 From: Ben Carman Date: Fri, 24 Apr 2020 09:43:19 -0500 Subject: [PATCH] Make fundWalletWithBitcoind have the same utxo amounts as FundedWallet (#1364) --- .../testkit/wallet/BitcoinSWalletTest.scala | 61 ++++++++++++++----- .../testkit/wallet/FundWalletUtil.scala | 27 ++++++++ 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/testkit/src/main/scala/org/bitcoins/testkit/wallet/BitcoinSWalletTest.scala b/testkit/src/main/scala/org/bitcoins/testkit/wallet/BitcoinSWalletTest.scala index 922f3f2e20..1064eea01c 100644 --- a/testkit/src/main/scala/org/bitcoins/testkit/wallet/BitcoinSWalletTest.scala +++ b/testkit/src/main/scala/org/bitcoins/testkit/wallet/BitcoinSWalletTest.scala @@ -206,7 +206,7 @@ trait BitcoinSWalletTest extends BitcoinSFixture with WalletLogger { val builder: () => Future[WalletWithBitcoind] = composeBuildersAndWrapFuture( builder = { () => - createDefaultWallet(nodeApi, chainQueryApi) + BitcoinSWalletTest.createWallet2Accounts(nodeApi, chainQueryApi) }, dependentBuilder = { (wallet: Wallet) => createWalletWithBitcoind(wallet) @@ -378,7 +378,9 @@ object BitcoinSWalletTest extends WalletLogger { val walletWithBitcoindV19F = for { bitcoind <- bitcoindF api <- nodeChainQueryApiF - wallet <- createDefaultWallet(api.nodeApi, api.chainQueryApi, extraConfig) + wallet <- BitcoinSWalletTest.createWallet2Accounts(api.nodeApi, + api.chainQueryApi, + extraConfig) //we need to create a promise so we can inject the wallet with the callback //after we have created it into SyncUtil.getNodeChainQueryApiWalletCallback @@ -471,7 +473,7 @@ object BitcoinSWalletTest extends WalletLogger { system: ActorSystem): Future[WalletWithBitcoind] = { import system.dispatcher for { - wallet <- createDefaultWallet(nodeApi, chainQueryApi) + wallet <- BitcoinSWalletTest.createWallet2Accounts(nodeApi, chainQueryApi) withBitcoind <- createWalletWithBitcoind(wallet, versionOpt) funded <- fundWalletWithBitcoind(withBitcoind) } yield funded @@ -485,7 +487,7 @@ object BitcoinSWalletTest extends WalletLogger { system: ActorSystem): Future[WalletWithBitcoind] = { import system.dispatcher for { - wallet <- createDefaultWallet(nodeApi, chainQueryApi) + wallet <- BitcoinSWalletTest.createWallet2Accounts(nodeApi, chainQueryApi) withBitcoind <- createWalletWithBitcoind(wallet, bitcoindRpcClient) funded <- fundWalletWithBitcoind(withBitcoind) } yield funded @@ -495,17 +497,48 @@ object BitcoinSWalletTest extends WalletLogger { def fundWalletWithBitcoind[T <: WalletWithBitcoind](pair: T)( implicit ec: ExecutionContext): Future[T] = { val (wallet, bitcoind) = (pair.wallet, pair.bitcoind) + + val defaultAcctAmts = Vector(1.bitcoin, 2.bitcoin, 3.bitcoin) + val expectedDefaultAmt = defaultAcctAmts.fold(CurrencyUnits.zero)(_ + _) + val account1Amt = Vector(Bitcoins(0.2), Bitcoins(0.3), Bitcoins(0.5)) + val expectedAccount1Amt = account1Amt.fold(CurrencyUnits.zero)(_ + _) + + val defaultAccount = wallet.walletConfig.defaultAccount + val fundedDefaultAccountWalletF = + FundWalletUtil.fundAccountForWalletWithBitcoind( + amts = defaultAcctAmts, + account = defaultAccount, + wallet = wallet, + bitcoind = bitcoind + ) + + val hdAccount1 = WalletTestUtil.getHdAccount1(wallet.walletConfig) + val fundedAccount1WalletF = for { + fundedDefaultAcct <- fundedDefaultAccountWalletF + fundedAcct1 <- FundWalletUtil.fundAccountForWalletWithBitcoind( + amts = account1Amt, + account = hdAccount1, + wallet = fundedDefaultAcct, + bitcoind = bitcoind + ) + } yield fundedAcct1 + + //sanity check to make sure we have money for { - addr <- wallet.getNewAddress() - txId <- bitcoind.sendToAddress(addr, initialFunds) - _ <- bitcoind.getNewAddress.flatMap(bitcoind.generateToAddress(6, _)) - tx <- bitcoind.getRawTransaction(txId) - _ <- wallet.processTransaction(tx.hex, tx.blockhash) - balance <- wallet.getBalance() - } yield { - assert(balance >= initialFunds) - pair - } + fundedWallet <- fundedAccount1WalletF + balance <- fundedWallet.getBalance(defaultAccount) + _ = require( + balance == expectedDefaultAmt, + s"Funding wallet fixture failed to fund the wallet, got balance=$balance expected=$expectedDefaultAmt") + + account1Balance <- fundedWallet.getBalance(hdAccount1) + _ = require( + account1Balance == expectedAccount1Amt, + s"Funding wallet fixture failed to fund account 1, " + + s"got balance=$hdAccount1 expected=$expectedAccount1Amt" + ) + + } yield pair } def destroyWalletWithBitcoind(walletWithBitcoind: WalletWithBitcoind)( diff --git a/testkit/src/main/scala/org/bitcoins/testkit/wallet/FundWalletUtil.scala b/testkit/src/main/scala/org/bitcoins/testkit/wallet/FundWalletUtil.scala index ca815d7104..a133b534ca 100644 --- a/testkit/src/main/scala/org/bitcoins/testkit/wallet/FundWalletUtil.scala +++ b/testkit/src/main/scala/org/bitcoins/testkit/wallet/FundWalletUtil.scala @@ -7,6 +7,7 @@ import org.bitcoins.core.currency.{Bitcoins, CurrencyUnit, CurrencyUnits, _} import org.bitcoins.core.hd.HDAccount import org.bitcoins.core.protocol.BitcoinAddress import org.bitcoins.core.protocol.transaction.TransactionOutput +import org.bitcoins.rpc.client.common.BitcoindRpcClient import org.bitcoins.server.BitcoinSAppConfig import org.bitcoins.testkit.util.TransactionTestUtil import org.bitcoins.testkit.wallet.FundWalletUtil.FundedWallet @@ -45,6 +46,32 @@ trait FundWalletUtil { fundedWalletF.map(_.asInstanceOf[Wallet]) } + def fundAccountForWalletWithBitcoind( + amts: Vector[CurrencyUnit], + account: HDAccount, + wallet: Wallet, + bitcoind: BitcoindRpcClient)( + implicit ec: ExecutionContext): Future[Wallet] = { + + val addressesF: Future[Vector[BitcoinAddress]] = Future.sequence { + Vector.fill(3)(wallet.getNewAddress(account)) + } + + val txAndHashF = for { + addresses <- addressesF + addressAmountMap = addresses.zip(amts).toMap + txId <- bitcoind.sendMany(addressAmountMap) + tx <- bitcoind.getRawTransactionRaw(txId) + hashes <- bitcoind.getNewAddress.flatMap(bitcoind.generateToAddress(6, _)) + } yield (tx, hashes.head) + + val fundedWalletF = + txAndHashF.map(txAndHash => + wallet.processTransaction(txAndHash._1, Some(txAndHash._2))) + + fundedWalletF.flatMap(_.map(_.asInstanceOf[Wallet])) + } + /** Funds a bitcoin-s wallet with 3 utxos with 1, 2 and 3 bitcoin in the utxos */ def fundWallet(wallet: Wallet)( implicit ec: ExecutionContext): Future[FundedWallet] = {