Add FundTransactionHandlingApi, make FundTransactionHandling a case class (#5651)

This commit is contained in:
Chris Stewart 2024-08-25 08:52:19 -05:00 committed by GitHub
parent 24e22a48e7
commit 2d4a0adda4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 107 additions and 57 deletions

View file

@ -0,0 +1,32 @@
package org.bitcoins.core.api.wallet
import org.bitcoins.core.api.wallet.db.AccountDb
import org.bitcoins.core.protocol.transaction.TransactionOutput
import org.bitcoins.core.wallet.builder.{
FundRawTxHelper,
ShufflingNonInteractiveFinalizer
}
import org.bitcoins.core.wallet.fee.FeeUnit
import org.bitcoins.core.wallet.utxo.AddressTag
import scala.concurrent.Future
trait FundTransactionHandlingApi {
def fundRawTransaction(
destinations: Vector[TransactionOutput],
feeRate: FeeUnit,
fromAccount: AccountDb,
markAsReserved: Boolean)
: Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]]
/** Funds a transaction from the wallet.
* @return
* funded transaction send funds to desinations with the given fee rate
*/
def fundRawTransaction(
destinations: Vector[TransactionOutput],
feeRate: FeeUnit,
fromTagOpt: Option[AddressTag],
markAsReserved: Boolean)
: Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]]
}

View file

@ -31,6 +31,7 @@ trait HDWalletApi extends WalletApi with AccountHandlingApi {
override def keyManager: BIP39KeyManagerApi
def accountHandling: AccountHandlingApi
def fundTxHandling: FundTransactionHandlingApi
/** Gets the balance of the given account */
def getBalance(account: HDAccount)(implicit
@ -509,5 +510,10 @@ trait HDWalletApi extends WalletApi with AccountHandlingApi {
feeRate: FeeUnit,
fromAccount: AccountDb,
markAsReserved: Boolean)
: Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]]
: Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]] = {
fundTxHandling.fundRawTransaction(destinations,
feeRate,
fromAccount,
markAsReserved)
}
}

View file

@ -18,10 +18,6 @@ import org.bitcoins.core.protocol.transaction.{
TransactionOutput
}
import org.bitcoins.core.util.{FutureUtil, StartStopAsync}
import org.bitcoins.core.wallet.builder.{
FundRawTxHelper,
ShufflingNonInteractiveFinalizer
}
import org.bitcoins.core.wallet.fee.FeeUnit
import org.bitcoins.core.wallet.utxo.{
AddressTag,
@ -98,17 +94,6 @@ trait WalletApi extends StartStopAsync[WalletApi] {
def findTransaction(txId: DoubleSha256DigestBE): Future[Option[TransactionDb]]
/** Funds a transaction from the wallet.
* @return
* funded transaction send funds to desinations with the given fee rate
*/
def fundRawTransaction(
destinations: Vector[TransactionOutput],
feeRate: FeeUnit,
fromTagOpt: Option[AddressTag],
markAsReserved: Boolean)
: Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]]
def listTransactions(): Future[Vector[TransactionDb]]
/** Gets the sum of all UTXOs in this wallet */

View file

@ -406,7 +406,7 @@ abstract class DLCWallet
nextIndex <- getNextAvailableIndex(account, chainType)
_ <- writeDLCKeysToAddressDb(account, chainType, nextIndex)
fundRawTxHelper <- fundRawTransactionInternal(
fundRawTxHelper <- fundTxHandling.fundRawTransactionInternal(
destinations = Vector(TransactionOutput(collateral, EmptyScriptPubKey)),
feeRate = feeRate,
fromAccount = account,
@ -810,7 +810,7 @@ abstract class DLCWallet
val txBuilderAndSpendingInfosF
: Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]] = {
for {
fundRawTxHelper <- fundRawTransactionInternal(
fundRawTxHelper <- fundTxHandling.fundRawTransactionInternal(
destinations =
Vector(TransactionOutput(collateral, EmptyScriptPubKey)),
feeRate = offer.feeRate,

View file

@ -84,7 +84,7 @@ class AddressTagIntegrationTest extends BitcoinSWalletTest {
feeRate <- wallet.getFeeRate()
rawTxHelper <- bitcoind.getNewAddress.flatMap { addr =>
val output = TransactionOutput(valueToBitcoind, addr.scriptPubKey)
wallet
wallet.fundTxHandling
.fundRawTransaction(
destinations = Vector(output),
feeRate = feeRate,

View file

@ -39,7 +39,7 @@ class FundTransactionHandlingTest
val wallet = fundedWallet.wallet
for {
feeRate <- wallet.getFeeRate()
fundRawTxHelper <- wallet.fundRawTransaction(
fundRawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
destinations = Vector(destination),
feeRate = feeRate,
fromTagOpt = None,
@ -66,7 +66,7 @@ class FundTransactionHandlingTest
val wallet = fundedWallet.wallet
for {
feeRate <- wallet.getFeeRate()
fundRawTxHelper <- wallet.fundRawTransaction(
fundRawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
destinations = Vector(newDestination),
feeRate = feeRate,
fromTagOpt = None,
@ -93,7 +93,7 @@ class FundTransactionHandlingTest
for {
feeRate <- wallet.getFeeRate()
fundRawTxHelper <- wallet.fundRawTransaction(
fundRawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
destinations = destinations,
feeRate = feeRate,
fromTagOpt = None,
@ -125,7 +125,7 @@ class FundTransactionHandlingTest
val fundedTxF = for {
feeRate <- wallet.getFeeRate()
fundedTx <- wallet.fundRawTransaction(
fundedTx <- wallet.fundTxHandling.fundRawTransaction(
destinations = Vector(tooBigOutput),
feeRate = feeRate,
fromTagOpt = None,
@ -147,7 +147,7 @@ class FundTransactionHandlingTest
val fundedTxF = for {
feeRate <- wallet.getFeeRate()
fundedTx <- wallet.fundRawTransaction(
fundedTx <- wallet.fundTxHandling.fundRawTransaction(
destinations = Vector(tooBigOutput),
feeRate = feeRate,
fromTagOpt = None,
@ -250,7 +250,7 @@ class FundTransactionHandlingTest
val wallet = fundedWallet.wallet
for {
feeRate <- wallet.getFeeRate()
fundRawTxHelper <- wallet.fundRawTransaction(
fundRawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
destinations = Vector(destination),
feeRate = feeRate,
fromTagOpt = None,
@ -281,7 +281,7 @@ class FundTransactionHandlingTest
expectedUtxos <- wallet.listUtxos(tag)
fundRawTxHelper <-
wallet
wallet.fundTxHandling
.fundRawTransaction(
destinations = Vector(destination),
feeRate = feeRate,

View file

@ -168,7 +168,7 @@ class ProcessTransactionTest extends BitcoinSWalletTest {
)
} yield fundingTx
val processedFundingTxF: Future[WalletApi] = for {
val processedFundingTxF: Future[Wallet] = for {
(fundingTx, _) <- fundingTxF
// make sure wallet is empty
balance <- wallet.getBalance()
@ -185,7 +185,7 @@ class ProcessTransactionTest extends BitcoinSWalletTest {
destinations = Vector(
TransactionOutput(amount, receivingAddress.scriptPubKey)
)
rawTxHelper <- wallet.fundRawTransaction(
rawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
destinations = destinations,
feeRate = SatoshisPerByte.one,
fromTagOpt = None,

View file

@ -480,7 +480,7 @@ class UTXOLifeCycleTest
for {
oldTransactions <- wallet.listTransactions()
feeRate <- wallet.getFeeRate()
rawTxHelper <- wallet.fundRawTransaction(
rawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
Vector(dummyOutput),
feeRate,
fromTagOpt = None,
@ -509,7 +509,7 @@ class UTXOLifeCycleTest
for {
oldTransactions <- wallet.listTransactions()
feeRate <- wallet.getFeeRate()
rawTxHelper <- wallet.fundRawTransaction(
rawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
Vector(dummyOutput),
feeRate,
fromTagOpt = None,
@ -542,7 +542,7 @@ class UTXOLifeCycleTest
for {
oldTransactions <- wallet.listTransactions()
feeRate <- wallet.getFeeRate()
rawTxHelper <- wallet.fundRawTransaction(
rawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
Vector(dummyOutput),
feeRate,
fromTagOpt = None,

View file

@ -49,7 +49,6 @@ import scala.util.{Failure, Random, Success}
abstract class Wallet
extends NeutrinoHDWalletApi
with AddressHandling
with FundTransactionHandling
with TransactionProcessing
with RescanHandling
with WalletLogger {
@ -95,6 +94,15 @@ abstract class Wallet
def utxoHandling: UtxoHandling =
UtxoHandling(spendingInfoDAO, transactionDAO, chainQueryApi)
def fundTxHandling: FundTransactionHandling = FundTransactionHandling(
accountHandling = this,
utxoHandling = utxoHandling,
addressHandling = this,
spendingInfoDAO = spendingInfoDAO,
transactionDAO = transactionDAO,
keyManager = keyManager
)
def accountHandling: AccountHandlingApi = AccountHandling(accountDAO)
def walletCallbacks: WalletCallbacks = walletConfig.callBacks
@ -621,7 +629,7 @@ abstract class Wallet
logger.info(s"Sending $amount to $address at feerate $feeRate")
val destination = TransactionOutput(amount, address.scriptPubKey)
for {
rawTxHelper <- fundRawTransactionInternal(
rawTxHelper <- fundTxHandling.fundRawTransactionInternal(
destinations = Vector(destination),
feeRate = feeRate,
fromAccount = fromAccount,
@ -712,7 +720,7 @@ abstract class Wallet
val output = TransactionOutput(0.satoshis, scriptPubKey)
for {
fundRawTxHelper <- fundRawTransactionInternal(
fundRawTxHelper <- fundTxHandling.fundRawTransactionInternal(
destinations = Vector(output),
feeRate = feeRate,
fromAccount = fromAccount,
@ -736,7 +744,7 @@ abstract class Wallet
newTags: Vector[AddressTag]
)(implicit ec: ExecutionContext): Future[Transaction] = {
for {
fundRawTxHelper <- fundRawTransactionInternal(
fundRawTxHelper <- fundTxHandling.fundRawTransactionInternal(
destinations = outputs,
feeRate = feeRate,
fromAccount = fromAccount,

View file

@ -69,6 +69,8 @@ class WalletHolder(initWalletOpt: Option[DLCNeutrinoHDWalletApi])(implicit
override def accountHandling: AccountHandlingApi = wallet.accountHandling
override def fundTxHandling: FundTransactionHandlingApi =
wallet.fundTxHandling
def isInitialized: Boolean = synchronized {
walletOpt.isDefined
}
@ -160,14 +162,14 @@ class WalletHolder(initWalletOpt: Option[DLCNeutrinoHDWalletApi])(implicit
txId: DoubleSha256DigestBE
): Future[Option[TransactionDb]] = delegate(_.findTransaction(txId))
override def fundRawTransaction(
destinations: Vector[TransactionOutput],
feeRate: FeeUnit,
fromTagOpt: Option[AddressTag],
markAsReserved: Boolean
): Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]] = delegate(
_.fundRawTransaction(destinations, feeRate, fromTagOpt, markAsReserved)
)
// override def fundRawTransaction(
// destinations: Vector[TransactionOutput],
// feeRate: FeeUnit,
// fromTagOpt: Option[AddressTag],
// markAsReserved: Boolean
// ): Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]] = delegate(
// _.fundRawTransaction(destinations, feeRate, fromTagOpt, markAsReserved)
// )
override def fundRawTransaction(
destinations: Vector[TransactionOutput],

View file

@ -1,30 +1,47 @@
package org.bitcoins.wallet.internal
import org.bitcoins.core.api.wallet._
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.core.api.keymanager.BIP39KeyManagerApi
import org.bitcoins.core.api.wallet.*
import org.bitcoins.core.api.wallet.db.AccountDb
import org.bitcoins.core.hd.HDAccount
import org.bitcoins.core.policy.Policy
import org.bitcoins.core.protocol.transaction._
import org.bitcoins.core.wallet.builder._
import org.bitcoins.core.protocol.transaction.*
import org.bitcoins.core.wallet.builder.*
import org.bitcoins.core.wallet.fee.FeeUnit
import org.bitcoins.core.wallet.utxo._
import org.bitcoins.wallet.{Wallet, WalletLogger}
import org.bitcoins.core.wallet.utxo.*
import org.bitcoins.db.SafeDatabase
import org.bitcoins.wallet.config.WalletAppConfig
import org.bitcoins.wallet.models.{SpendingInfoDAO, TransactionDAO}
import org.bitcoins.wallet.WalletLogger
import slick.dbio.{DBIO, DBIOAction, Effect, NoStream}
import scala.concurrent.Future
trait FundTransactionHandling extends WalletLogger { self: Wallet =>
import walletConfig.profile.api._
case class FundTransactionHandling(
accountHandling: AccountHandlingApi,
utxoHandling: UtxoHandling,
addressHandling: AddressHandling,
spendingInfoDAO: SpendingInfoDAO,
transactionDAO: TransactionDAO,
keyManager: BIP39KeyManagerApi)(implicit
walletConfig: WalletAppConfig,
system: ActorSystem)
extends FundTransactionHandlingApi
with WalletLogger {
// import walletConfig.profile.api._
import org.bitcoins.core.currency.currencyUnitNumeric
import system.dispatcher
private val safeDatabase: SafeDatabase = spendingInfoDAO.safeDatabase
def utxoHandling: UtxoHandling
def fundRawTransaction(
override def fundRawTransaction(
destinations: Vector[TransactionOutput],
feeRate: FeeUnit,
fromTagOpt: Option[AddressTag],
markAsReserved: Boolean
): Future[FundRawTxHelper[ShufflingNonInteractiveFinalizer]] = {
for {
account <- getDefaultAccount()
account <- accountHandling.getDefaultAccount()
funded <- fundRawTransaction(
destinations = destinations,
feeRate = feeRate,
@ -52,7 +69,7 @@ trait FundTransactionHandling extends WalletLogger { self: Wallet =>
}
/** Funds an unsigned transaction from the specified account */
def fundRawTransaction(
override def fundRawTransaction(
destinations: Vector[TransactionOutput],
feeRate: FeeUnit,
fromAccount: AccountDb,
@ -162,7 +179,7 @@ trait FundTransactionHandling extends WalletLogger { self: Wallet =>
walletUtxos = selectableUtxos,
outputs = destinations,
feeRate = feeRate,
longTermFeeRateOpt = Some(self.walletConfig.longTermFeeRate)
longTermFeeRateOpt = Some(walletConfig.longTermFeeRate)
)
filtered = walletUtxos.filter(utxo =>
utxos.exists(_.outPoint == utxo._1.outPoint))
@ -174,10 +191,10 @@ trait FundTransactionHandling extends WalletLogger { self: Wallet =>
for {
(selectedUtxos, callbackF) <- selectedUtxosA
change <- getNewChangeAddressAction(fromAccount)
change <- addressHandling.getNewChangeAddressAction(fromAccount)
utxoSpendingInfos = {
selectedUtxos.map { case (utxo, prevTx) =>
utxo.toUTXOInfo(keyManager = self.keyManager, prevTx)
utxo.toUTXOInfo(keyManager = keyManager, prevTx)
}
}
} yield {