mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 10:46:42 +01:00
Refactor TransactionProcessing.processTransaction()
to use BlockHashWithConfs
(#5744)
* Refactor TransactionProcessing.processTransaction() to use BlockHashWithConfs Create WalletUtil.getBlockHashWithConfs(), use it in various places through the codebase * Fix docs
This commit is contained in:
parent
2521c5da0e
commit
f75a52b521
19 changed files with 240 additions and 160 deletions
|
@ -25,7 +25,7 @@ object CallbackUtil extends BitcoinSLogger {
|
|||
val txSink = Sink.foreachAsync[Transaction](1) { case tx: Transaction =>
|
||||
logger.debug(s"Receiving transaction txid=${tx.txIdBE.hex} as a callback")
|
||||
wallet.transactionProcessing
|
||||
.processTransaction(tx, blockHashOpt = None)
|
||||
.processTransaction(tx, blockHashWithConfsOpt = None)
|
||||
.map(_ => ())
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ object CallbackUtil extends BitcoinSLogger {
|
|||
val txSink = Sink.foreachAsync[Transaction](1) { case tx: Transaction =>
|
||||
logger.debug(s"Receiving transaction txid=${tx.txIdBE.hex} as a callback")
|
||||
wallet.transactionProcessing
|
||||
.processTransaction(tx, blockHashOpt = None)
|
||||
.processTransaction(tx, blockHashWithConfsOpt = None)
|
||||
.map(_ => ())
|
||||
}
|
||||
val onTx: OnTxReceived = { tx =>
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.bitcoins.core.api.wallet.db.{SpendingInfoDb, TransactionDb}
|
|||
import org.bitcoins.core.currency.CurrencyUnit
|
||||
import org.bitcoins.core.protocol.blockchain.Block
|
||||
import org.bitcoins.core.protocol.transaction.{OutputWithIndex, Transaction}
|
||||
import org.bitcoins.core.util.BlockHashWithConfs
|
||||
import org.bitcoins.core.wallet.fee.FeeUnit
|
||||
import org.bitcoins.core.wallet.utxo.AddressTag
|
||||
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
|
||||
|
@ -26,7 +27,7 @@ trait TransactionProcessingApi {
|
|||
|
||||
def processTransaction(
|
||||
transaction: Transaction,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE]
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs]
|
||||
): Future[Unit]
|
||||
|
||||
/** Processes TXs originating from our wallet. This is called right after
|
||||
|
@ -37,7 +38,7 @@ trait TransactionProcessingApi {
|
|||
feeRate: FeeUnit,
|
||||
inputAmount: CurrencyUnit,
|
||||
sentAmount: CurrencyUnit,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE],
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs],
|
||||
newTags: Vector[AddressTag]
|
||||
): Future[ProcessTxResult]
|
||||
|
||||
|
@ -52,7 +53,7 @@ trait TransactionProcessingApi {
|
|||
|
||||
def processReceivedUtxos(
|
||||
tx: Transaction,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE],
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs],
|
||||
spendingInfoDbs: Vector[SpendingInfoDb],
|
||||
newTags: Vector[AddressTag],
|
||||
relevantReceivedOutputs: Vector[OutputWithIndex]
|
||||
|
@ -61,7 +62,7 @@ trait TransactionProcessingApi {
|
|||
def processSpentUtxos(
|
||||
transaction: Transaction,
|
||||
outputsBeingSpent: Vector[SpendingInfoDb],
|
||||
blockHashOpt: Option[DoubleSha256DigestBE]
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs]
|
||||
): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def insertTransaction(
|
||||
|
|
|
@ -5,6 +5,7 @@ import org.bitcoins.core.protocol.dlc.models.{
|
|||
DLCStatus,
|
||||
SingleContractInfo
|
||||
}
|
||||
import org.bitcoins.core.util.BlockHashWithConfs
|
||||
import org.bitcoins.dlc.wallet.callback.{DLCWalletCallbacks, OnDLCStateChange}
|
||||
import org.bitcoins.testkit.wallet.FundWalletUtil.FundedDLCWallet
|
||||
import org.bitcoins.testkit.wallet.{BitcoinSDualWalletTest, DLCWalletUtil}
|
||||
|
@ -96,9 +97,11 @@ class DLCWalletCallbackTest extends BitcoinSDualWalletTest {
|
|||
_ <- initF
|
||||
contractId <- DLCWalletUtil.getContractId(wallets._1.wallet)
|
||||
fundingTx <- walletA.getDLCFundingTx(contractId)
|
||||
blockHash = CryptoGenerators.doubleSha256DigestBE.sample.get
|
||||
blockHashWithConfs = BlockHashWithConfs(blockHash, Some(1))
|
||||
_ <- walletA.transactionProcessing.processTransaction(
|
||||
transaction = fundingTx,
|
||||
blockHashOpt = Some(CryptoGenerators.doubleSha256DigestBE.sample.get)
|
||||
blockHashWithConfsOpt = Some(blockHashWithConfs)
|
||||
)
|
||||
sigs = {
|
||||
DLCWalletUtil.sampleContractInfo match {
|
||||
|
@ -207,9 +210,11 @@ class DLCWalletCallbackTest extends BitcoinSDualWalletTest {
|
|||
_ <- initF
|
||||
contractId <- DLCWalletUtil.getContractId(wallets._1.wallet)
|
||||
fundingTx <- walletA.getDLCFundingTx(contractId)
|
||||
blockHash = CryptoGenerators.doubleSha256DigestBE.sample.get
|
||||
blockHashWithConfs = BlockHashWithConfs(blockHash, Some(1))
|
||||
_ <- walletA.transactionProcessing.processTransaction(
|
||||
transaction = fundingTx,
|
||||
blockHashOpt = Some(CryptoGenerators.doubleSha256DigestBE.sample.get)
|
||||
blockHashWithConfsOpt = Some(blockHashWithConfs)
|
||||
)
|
||||
transaction <- walletA.executeDLCRefund(contractId)
|
||||
_ <- walletB.transactionProcessing.processTransaction(transaction, None)
|
||||
|
|
|
@ -1935,7 +1935,8 @@ case class DLCWallet(override val walletApi: Wallet)(implicit
|
|||
_ <- updateClosingTxId(contractId, refundTx.txIdBE)
|
||||
|
||||
_ <- transactionProcessing.processTransaction(refundTx,
|
||||
blockHashOpt = None)
|
||||
blockHashWithConfsOpt =
|
||||
None)
|
||||
status <- findDLC(dlcDb.dlcId)
|
||||
_ <- dlcConfig.walletCallbacks.executeOnDLCStateChange(status.get)
|
||||
} yield refundTx
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.bitcoins.core.protocol.transaction.{
|
|||
WitnessTransaction
|
||||
}
|
||||
import org.bitcoins.core.psbt.InputPSBTRecord.PartialSignature
|
||||
import org.bitcoins.core.util.FutureUtil
|
||||
import org.bitcoins.core.util.{BlockHashWithConfs, FutureUtil}
|
||||
import org.bitcoins.core.wallet.fee.FeeUnit
|
||||
import org.bitcoins.core.wallet.utxo.{
|
||||
AddressTag,
|
||||
|
@ -519,23 +519,25 @@ case class DLCTransactionProcessing(
|
|||
|
||||
override def processTransaction(
|
||||
transaction: Transaction,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE]): Future[Unit] = {
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs]): Future[Unit] = {
|
||||
txProcessing
|
||||
.processTransaction(transaction, blockHashOpt)
|
||||
.flatMap(_ => processFundingTx(transaction, blockHashOpt))
|
||||
.flatMap(_ => processSettledDLCs(transaction, blockHashOpt))
|
||||
.processTransaction(transaction, blockHashWithConfsOpt)
|
||||
.flatMap(_ =>
|
||||
processFundingTx(transaction, blockHashWithConfsOpt.map(_.blockHash)))
|
||||
.flatMap(_ =>
|
||||
processSettledDLCs(transaction, blockHashWithConfsOpt.map(_.blockHash)))
|
||||
.map(_ => ())
|
||||
}
|
||||
|
||||
override def processReceivedUtxos(
|
||||
tx: Transaction,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE],
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs],
|
||||
spendingInfoDbs: Vector[SpendingInfoDb],
|
||||
newTags: Vector[AddressTag],
|
||||
relevantReceivedOutputs: Vector[OutputWithIndex])
|
||||
: Future[Vector[SpendingInfoDb]] = {
|
||||
txProcessing.processReceivedUtxos(tx,
|
||||
blockHashOpt,
|
||||
blockHashWithConfsOpt,
|
||||
spendingInfoDbs,
|
||||
newTags,
|
||||
relevantReceivedOutputs)
|
||||
|
@ -544,9 +546,11 @@ case class DLCTransactionProcessing(
|
|||
override def processSpentUtxos(
|
||||
transaction: Transaction,
|
||||
outputsBeingSpent: Vector[SpendingInfoDb],
|
||||
blockHashOpt: Option[DoubleSha256DigestBE])
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs])
|
||||
: Future[Vector[SpendingInfoDb]] = {
|
||||
txProcessing.processSpentUtxos(transaction, outputsBeingSpent, blockHashOpt)
|
||||
txProcessing.processSpentUtxos(transaction,
|
||||
outputsBeingSpent,
|
||||
blockHashWithConfsOpt)
|
||||
}
|
||||
|
||||
/** Processes TXs originating from our wallet. This is called right after
|
||||
|
@ -557,13 +561,13 @@ case class DLCTransactionProcessing(
|
|||
feeRate: FeeUnit,
|
||||
inputAmount: CurrencyUnit,
|
||||
sentAmount: CurrencyUnit,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE],
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs],
|
||||
newTags: Vector[AddressTag]): Future[ProcessTxResult] = {
|
||||
txProcessing.processOurTransaction(transaction,
|
||||
feeRate,
|
||||
inputAmount,
|
||||
sentAmount,
|
||||
blockHashOpt,
|
||||
blockHashWithConfsOpt,
|
||||
newTags)
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,9 @@ import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
|||
import org.bitcoins.rpc.config._
|
||||
import org.bitcoins.wallet.config.WalletAppConfig
|
||||
import org.bitcoins.core.api.wallet.WalletApi
|
||||
import org.bitcoins.core.util.BlockHashWithConfs
|
||||
import org.bitcoins.wallet.Wallet
|
||||
import org.bitcoins.wallet.util.WalletUtil
|
||||
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import java.nio.file.Files
|
||||
|
@ -157,12 +159,13 @@ val walletF: Future[WalletApi] = configF.flatMap { _ =>
|
|||
|
||||
// when this future completes, ww have sent a transaction
|
||||
// from bitcoind to the Bitcoin-S wallet
|
||||
val transactionF: Future[(Transaction, Option[DoubleSha256DigestBE])] = for {
|
||||
val transactionF: Future[(Transaction, Option[BlockHashWithConfs])] = for {
|
||||
wallet <- walletF
|
||||
address <- wallet.getNewAddress()
|
||||
txid <- bitcoind.sendToAddress(address, 3.bitcoin)
|
||||
transaction <- bitcoind.getRawTransaction(txid)
|
||||
} yield (transaction.hex, transaction.blockhash)
|
||||
blockHashWithConfs <- WalletUtil.getBlockHashWithConfs(bitcoind,transaction.blockhash)
|
||||
} yield (transaction.hex, blockHashWithConfs)
|
||||
|
||||
// when this future completes, we have processed
|
||||
// the transaction from bitcoind, and we have
|
||||
|
|
|
@ -5,7 +5,7 @@ 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.core.util.{BlockHashWithConfs, FutureUtil}
|
||||
import org.bitcoins.crypto.DoubleSha256DigestBE
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
@ -19,6 +19,9 @@ object MockChainQueryApi extends ChainQueryApi {
|
|||
"00000000496dcc754fabd97f3e2df0a7337eab417d75537fecf97a7ebb0e7c75"
|
||||
)
|
||||
|
||||
val blockHashWithConfs: BlockHashWithConfs =
|
||||
BlockHashWithConfs(testBlockHash, Some(6))
|
||||
|
||||
/** Gets the height of the given block */
|
||||
override def getBlockHeight(
|
||||
blockHash: DoubleSha256DigestBE
|
||||
|
@ -41,7 +44,7 @@ object MockChainQueryApi extends ChainQueryApi {
|
|||
blockHash: DoubleSha256DigestBE
|
||||
): Future[Option[Int]] = {
|
||||
if (blockHash == testBlockHash) {
|
||||
Future.successful(Some(6))
|
||||
Future.successful(blockHashWithConfs.confirmationsOpt)
|
||||
} else FutureUtil.none
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.bitcoins.testkit.wallet.FundWalletUtil.{
|
|||
import org.bitcoins.testkitcore.gen.TransactionGenerators
|
||||
import org.bitcoins.testkitcore.util.TransactionTestUtil
|
||||
import org.bitcoins.wallet.config.WalletAppConfig
|
||||
import org.bitcoins.wallet.util.WalletUtil
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
|
@ -107,7 +108,10 @@ trait FundWalletUtil extends BitcoinSLogger {
|
|||
addresses <- addressesF
|
||||
addressAmountMap = addresses.zip(amts).toMap
|
||||
(tx, blockHash) <- fundAddressesWithBitcoind(addressAmountMap, bitcoind)
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, Some(blockHash))
|
||||
blockHashWithConfs <- WalletUtil.getBlockHashWithConfs(bitcoind,
|
||||
blockHash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx,
|
||||
blockHashWithConfs)
|
||||
} yield (tx, blockHash)
|
||||
|
||||
txAndHashF.map(_ => wallet)
|
||||
|
|
|
@ -75,17 +75,18 @@ class ProcessTransactionTest extends BitcoinSWalletTest {
|
|||
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
tx,
|
||||
Some(MockChainQueryApi.testBlockHash)
|
||||
Some(MockChainQueryApi.blockHashWithConfs)
|
||||
)
|
||||
newConfirmed <- wallet.getConfirmedBalance()
|
||||
newUnconfirmed <- wallet.getUnconfirmedBalance()
|
||||
utxosPostAdd <- wallet.utxoHandling.listUtxos()
|
||||
|
||||
// repeating the action should not make a difference
|
||||
|
||||
_ <- checkUtxosAndBalance(wallet) {
|
||||
wallet.transactionProcessing.processTransaction(
|
||||
tx,
|
||||
Some(MockChainQueryApi.testBlockHash))
|
||||
Some(MockChainQueryApi.blockHashWithConfs))
|
||||
}
|
||||
} yield {
|
||||
val ourOutputs =
|
||||
|
@ -196,7 +197,7 @@ class ProcessTransactionTest extends BitcoinSWalletTest {
|
|||
)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
transaction = rawTxHelper.signedTx,
|
||||
blockHashOpt = None
|
||||
blockHashWithConfsOpt = None
|
||||
)
|
||||
balance <- wallet.getBalance()
|
||||
} yield assert(balance == amount)
|
||||
|
|
|
@ -11,6 +11,8 @@ import org.bitcoins.testkit.wallet.{
|
|||
BitcoinSWalletTestCachedBitcoindNewest,
|
||||
WalletWithBitcoindRpc
|
||||
}
|
||||
import org.bitcoins.wallet.util.WalletUtil
|
||||
|
||||
import scala.concurrent.duration.DurationInt
|
||||
|
||||
class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
|
@ -110,9 +112,12 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
bitcoindAddr <- bitcoindAddrF
|
||||
blockHashes <-
|
||||
bitcoind.generateToAddress(blocks = numBlocks, address = bitcoindAddr)
|
||||
blockHashWithConfs <- WalletUtil.getBlockHashWithConfs(
|
||||
bitcoind,
|
||||
blockHashes.headOption)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
transaction = tx,
|
||||
blockHashOpt = blockHashes.headOption
|
||||
blockHashWithConfsOpt = blockHashWithConfs
|
||||
)
|
||||
balance <- wallet.getBalance()
|
||||
unconfirmedBalance <- wallet.getUnconfirmedBalance()
|
||||
|
@ -171,9 +176,12 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
bitcoindAddr <- bitcoindAddrF
|
||||
blockHashes <-
|
||||
bitcoind.generateToAddress(blocks = numBlocks, address = bitcoindAddr)
|
||||
blockHashWithConfs <- WalletUtil.getBlockHashWithConfs(
|
||||
bitcoind,
|
||||
blockHashes.headOption)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
transaction = tx,
|
||||
blockHashOpt = blockHashes.headOption
|
||||
blockHashWithConfsOpt = blockHashWithConfs
|
||||
)
|
||||
balance <- wallet.getBalance()
|
||||
unconfirmedBalance <- wallet.getUnconfirmedBalance()
|
||||
|
@ -235,9 +243,12 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
bitcoindAddr <- bitcoindAddrF
|
||||
blockHashes <-
|
||||
bitcoind.generateToAddress(blocks = numBlocks, address = bitcoindAddr)
|
||||
blockHashWithConfs <- WalletUtil.getBlockHashWithConfs(
|
||||
bitcoind,
|
||||
blockHashes.headOption)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
transaction = tx,
|
||||
blockHashOpt = blockHashes.headOption
|
||||
blockHashWithConfsOpt = blockHashWithConfs
|
||||
)
|
||||
balance <- wallet.getBalance()
|
||||
unconfirmedBalance <- wallet.getUnconfirmedBalance()
|
||||
|
@ -523,9 +534,12 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
bitcoindAddr <- bitcoindAddrF
|
||||
blockHashes <-
|
||||
bitcoind.generateToAddress(blocks = numBlocks, address = bitcoindAddr)
|
||||
blockHashWithConfs <- WalletUtil.getBlockHashWithConfs(
|
||||
bitcoind,
|
||||
blockHashes.headOption)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
transaction = tx,
|
||||
blockHashOpt = blockHashes.headOption
|
||||
blockHashWithConfsOpt = blockHashWithConfs
|
||||
)
|
||||
balance <- wallet.getBalance()
|
||||
unconfirmedBalance <- wallet.getUnconfirmedBalance()
|
||||
|
|
|
@ -4,21 +4,22 @@ import org.bitcoins.commons.util.BitcoinSLogger
|
|||
import org.bitcoins.core.api.wallet.CoinSelectionAlgo
|
||||
import org.bitcoins.core.api.wallet.db.SpendingInfoDb
|
||||
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
|
||||
import org.bitcoins.core.number._
|
||||
import org.bitcoins.core.number.*
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
import org.bitcoins.core.protocol.script._
|
||||
import org.bitcoins.core.protocol.transaction._
|
||||
import org.bitcoins.core.protocol.script.*
|
||||
import org.bitcoins.core.protocol.transaction.*
|
||||
import org.bitcoins.core.psbt.PSBT
|
||||
import org.bitcoins.core.wallet.builder.RawTxSigner
|
||||
import org.bitcoins.core.wallet.fee.{SatoshisPerByte, SatoshisPerVirtualByte}
|
||||
import org.bitcoins.core.wallet.utxo.TxoState
|
||||
import org.bitcoins.core.wallet.utxo.TxoState._
|
||||
import org.bitcoins.core.wallet.utxo.TxoState.*
|
||||
import org.bitcoins.crypto.{DoubleSha256DigestBE, ECPublicKey}
|
||||
import org.bitcoins.testkit.wallet.{
|
||||
BitcoinSWalletTestCachedBitcoindNewest,
|
||||
WalletWithBitcoindRpc
|
||||
}
|
||||
import org.bitcoins.wallet.models.SpendingInfoDAO
|
||||
import org.bitcoins.wallet.util.WalletUtil
|
||||
import org.scalatest.{Assertion, FutureOutcome, Outcome}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
@ -83,7 +84,9 @@ class UTXOLifeCycleTest
|
|||
|
||||
// Give tx a fake hash so it can appear as it's in a block
|
||||
hash <- bitcoind.getBestBlockHash()
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, Some(hash))
|
||||
blockHashWithConfs <- WalletUtil.getBlockHashWithConfs(bitcoind, hash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx,
|
||||
blockHashWithConfs)
|
||||
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
pendingCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
|
@ -345,7 +348,9 @@ class UTXOLifeCycleTest
|
|||
|
||||
// Give tx a fake hash so it can appear as it's in a block
|
||||
hash <- bitcoind.getBestBlockHash()
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, Some(hash))
|
||||
blockHashWithConfs <- WalletUtil.getBlockHashWithConfs(bitcoind, hash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx,
|
||||
blockHashWithConfs)
|
||||
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
pendingCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
|
@ -390,7 +395,7 @@ class UTXOLifeCycleTest
|
|||
feeRate = SatoshisPerByte(Satoshis(3)),
|
||||
inputAmount = Satoshis(4000),
|
||||
sentAmount = Satoshis(3000),
|
||||
blockHashOpt = None,
|
||||
blockHashWithConfsOpt = None,
|
||||
newTags = Vector.empty
|
||||
)
|
||||
|
||||
|
@ -419,7 +424,7 @@ class UTXOLifeCycleTest
|
|||
feeRate = SatoshisPerByte(Satoshis(3)),
|
||||
inputAmount = Satoshis(4000),
|
||||
sentAmount = Satoshis(3000),
|
||||
blockHashOpt = None,
|
||||
blockHashWithConfsOpt = None,
|
||||
newTags = Vector.empty
|
||||
)
|
||||
|
||||
|
@ -431,7 +436,10 @@ class UTXOLifeCycleTest
|
|||
hash <- bitcoind.getNewAddress
|
||||
.flatMap(bitcoind.generateToAddress(1, _))
|
||||
.map(_.head)
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, Some(hash))
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(bitcoind, hash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
tx,
|
||||
blockHashWithConfsOpt)
|
||||
|
||||
pendingCoins <-
|
||||
wallet.utxoHandling.findByScriptPubKey(addr.scriptPubKey)
|
||||
|
@ -456,12 +464,14 @@ class UTXOLifeCycleTest
|
|||
|
||||
txId <- bitcoind.sendToAddress(addr, Satoshis(3000))
|
||||
tx <- bitcoind.getRawTransactionRaw(txId)
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(bitcoind,
|
||||
Some(blockHash))
|
||||
_ <- wallet.transactionProcessing.processOurTransaction(
|
||||
transaction = tx,
|
||||
feeRate = SatoshisPerByte(Satoshis(3)),
|
||||
inputAmount = Satoshis(4000),
|
||||
sentAmount = Satoshis(3000),
|
||||
blockHashOpt = Some(blockHash), // give fake hash
|
||||
blockHashWithConfsOpt = blockHashWithConfsOpt, // give fake hash
|
||||
newTags = Vector.empty
|
||||
)
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.bitcoins.wallet.models.{
|
|||
IncomingTransactionDAO,
|
||||
OutgoingTransactionDAO
|
||||
}
|
||||
import org.bitcoins.wallet.util.WalletUtil
|
||||
import org.scalatest.{FutureOutcome, Outcome}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
@ -92,7 +93,11 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
rawTx <- bitcoind.getRawTransaction(txId)
|
||||
|
||||
// after this, tx should be confirmed
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, rawTx.blockhash)
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(bitcoind,
|
||||
rawTx.blockhash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
tx,
|
||||
blockHashWithConfsOpt)
|
||||
_ <-
|
||||
wallet.utxoHandling
|
||||
.listUtxos()
|
||||
|
@ -176,8 +181,11 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
txId <- bitcoind.sendToAddress(addr, valueFromBitcoind)
|
||||
rawTx <- bitcoind.getRawTransaction(txId)
|
||||
_ <- bitcoind.generate(6)
|
||||
_ <- wallet.transactionProcessing.processTransaction(rawTx.hex,
|
||||
rawTx.blockhash)
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(bitcoind,
|
||||
rawTx.blockhash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
rawTx.hex,
|
||||
blockHashWithConfsOpt)
|
||||
|
||||
// Verify we funded the wallet
|
||||
balance <- wallet.getBalance()
|
||||
|
@ -243,8 +251,11 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
txId <- bitcoind.sendToAddress(addr, valueFromBitcoind)
|
||||
_ <- bitcoind.generate(6)
|
||||
rawTx <- bitcoind.getRawTransaction(txId)
|
||||
_ <- wallet.transactionProcessing.processTransaction(rawTx.hex,
|
||||
rawTx.blockhash)
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(bitcoind,
|
||||
rawTx.blockhash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
rawTx.hex,
|
||||
blockHashWithConfsOpt)
|
||||
|
||||
// Verify we funded the wallet
|
||||
balance <- wallet.getBalance()
|
||||
|
@ -262,8 +273,11 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
_ <- bitcoind.generate(1)
|
||||
rawTx1 <- bitcoind.getRawTransaction(rbf.txIdBE)
|
||||
_ = require(rawTx1.blockhash.isDefined)
|
||||
_ <- wallet.transactionProcessing.processTransaction(rbf,
|
||||
rawTx1.blockhash)
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(bitcoind,
|
||||
rawTx.blockhash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
rbf,
|
||||
blockHashWithConfsOpt)
|
||||
|
||||
// fail to RBF confirmed tx
|
||||
res <- recoverToSucceededIf[IllegalArgumentException] {
|
||||
|
@ -283,8 +297,11 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
|||
txId <- bitcoind.sendToAddress(addr, valueFromBitcoind)
|
||||
rawTx <- bitcoind.getRawTransaction(txId)
|
||||
_ <- bitcoind.generate(6)
|
||||
_ <- wallet.transactionProcessing.processTransaction(rawTx.hex,
|
||||
rawTx.blockhash)
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(bitcoind,
|
||||
rawTx.blockhash)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
rawTx.hex,
|
||||
blockHashWithConfsOpt)
|
||||
|
||||
// Verify we funded the wallet
|
||||
balance <- wallet.getBalance()
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.bitcoins.testkitcore.Implicits.GeneratorOps
|
|||
import org.bitcoins.testkitcore.gen.FeeUnitGen
|
||||
import org.bitcoins.wallet.config.WalletAppConfig
|
||||
import org.bitcoins.wallet.models.{OutgoingTransactionDAO, SpendingInfoDAO}
|
||||
import org.bitcoins.wallet.util.WalletUtil
|
||||
import org.scalatest.{Assertion, FutureOutcome}
|
||||
import scodec.bits.ByteVector
|
||||
|
||||
|
@ -379,9 +380,12 @@ class WalletSendingTest extends BitcoinSWalletTest {
|
|||
tx <- wallet.sendFundsHandling.sendToAddress(testAddress,
|
||||
amountToSend,
|
||||
feeRate)
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(
|
||||
chainQueryApi,
|
||||
Some(DoubleSha256DigestBE.empty))
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
tx,
|
||||
Some(DoubleSha256DigestBE.empty))
|
||||
blockHashWithConfsOpt)
|
||||
|
||||
res <- recoverToSucceededIf[IllegalArgumentException] {
|
||||
wallet.sendFundsHandling.bumpFeeRBF(tx.txIdBE, newFeeRate)
|
||||
|
@ -470,9 +474,12 @@ class WalletSendingTest extends BitcoinSWalletTest {
|
|||
tx <- wallet.sendFundsHandling.sendToAddress(testAddress,
|
||||
amountToSend,
|
||||
feeRate)
|
||||
blockHashWithConfsOpt <- WalletUtil.getBlockHashWithConfs(
|
||||
chainQueryApi,
|
||||
Some(DoubleSha256DigestBE.empty))
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
tx,
|
||||
Some(DoubleSha256DigestBE.empty))
|
||||
blockHashWithConfsOpt)
|
||||
|
||||
res <- recoverToSucceededIf[IllegalArgumentException] {
|
||||
wallet.sendFundsHandling.bumpFeeCPFP(tx.txIdBE, feeRate)
|
||||
|
|
|
@ -254,9 +254,9 @@ class WalletUnitTest extends BitcoinSWalletTest {
|
|||
spk = addr.scriptPubKey
|
||||
_ = assert(spk == P2PKHScriptPubKey(walletKey))
|
||||
dummyPrevTx = dummyTx(spk = spk)
|
||||
_ <- wallet.transactionProcessing.processTransaction(dummyPrevTx,
|
||||
blockHashOpt =
|
||||
None)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
dummyPrevTx,
|
||||
blockHashWithConfsOpt = None)
|
||||
|
||||
psbt = dummyPSBT(prevTxId = dummyPrevTx.txId)
|
||||
|
||||
|
@ -280,9 +280,9 @@ class WalletUnitTest extends BitcoinSWalletTest {
|
|||
spk = addr.scriptPubKey
|
||||
_ = assert(spk == P2SHScriptPubKey(P2WPKHWitnessSPKV0(walletKey)))
|
||||
dummyPrevTx = dummyTx(spk = spk)
|
||||
_ <- wallet.transactionProcessing.processTransaction(dummyPrevTx,
|
||||
blockHashOpt =
|
||||
None)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
dummyPrevTx,
|
||||
blockHashWithConfsOpt = None)
|
||||
|
||||
psbt = dummyPSBT(prevTxId = dummyPrevTx.txId)
|
||||
|
||||
|
@ -306,9 +306,9 @@ class WalletUnitTest extends BitcoinSWalletTest {
|
|||
spk = addr.scriptPubKey
|
||||
_ = assert(spk == P2WPKHWitnessSPKV0(walletKey))
|
||||
dummyPrevTx = dummyTx(spk = spk)
|
||||
_ <- wallet.transactionProcessing.processTransaction(dummyPrevTx,
|
||||
blockHashOpt =
|
||||
None)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
dummyPrevTx,
|
||||
blockHashWithConfsOpt = None)
|
||||
|
||||
psbt = dummyPSBT(prevTxId = dummyPrevTx.txId)
|
||||
.addUTXOToInput(dummyPrevTx, 0)
|
||||
|
@ -339,12 +339,14 @@ class WalletUnitTest extends BitcoinSWalletTest {
|
|||
spk = addr.scriptPubKey
|
||||
_ = assert(spk == P2WPKHWitnessSPKV0(walletKey))
|
||||
dummyPrevTx = dummyTx(spk = spk)
|
||||
_ <- wallet.transactionProcessing.processTransaction(dummyPrevTx,
|
||||
blockHashOpt = None)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
dummyPrevTx,
|
||||
blockHashWithConfsOpt = None)
|
||||
|
||||
dummyPrevTx1 = dummyTx(prevTxId = dummyPrevTx.txId, spk = spk)
|
||||
_ <- wallet.transactionProcessing.processTransaction(dummyPrevTx1,
|
||||
blockHashOpt = None)
|
||||
_ <- wallet.transactionProcessing.processTransaction(
|
||||
dummyPrevTx1,
|
||||
blockHashWithConfsOpt = None)
|
||||
|
||||
toBroadcast <- wallet.sendFundsHandling.getTransactionsToBroadcast
|
||||
} yield assert(toBroadcast.map(_.txIdBE) == Vector(dummyPrevTx1.txIdBE))
|
||||
|
|
|
@ -232,7 +232,8 @@ case class Wallet(
|
|||
for {
|
||||
_ <- nodeApi.broadcastTransaction(transaction)
|
||||
_ <- transactionProcessing.processTransaction(transaction,
|
||||
blockHashOpt = None)
|
||||
blockHashWithConfsOpt =
|
||||
None)
|
||||
_ <- walletCallbacks.executeOnTransactionBroadcast(transaction)
|
||||
} yield ()
|
||||
|
||||
|
|
|
@ -604,7 +604,7 @@ case class SendFundsHandlingHandling(
|
|||
feeRate = feeRate,
|
||||
inputAmount = creditingAmount,
|
||||
sentAmount = sentAmount,
|
||||
blockHashOpt = None,
|
||||
blockHashWithConfsOpt = None,
|
||||
newTags = newTags
|
||||
)
|
||||
} yield {
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.bitcoins.wallet.models.{
|
|||
WalletDAOs,
|
||||
WalletStateDescriptorDAO
|
||||
}
|
||||
import org.bitcoins.wallet.util.WalletUtil
|
||||
import slick.dbio.{DBIOAction, Effect, NoStream}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
@ -82,13 +83,13 @@ case class TransactionProcessing(
|
|||
/** @inheritdoc */
|
||||
override def processTransaction(
|
||||
transaction: Transaction,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE]
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs]
|
||||
): Future[Unit] = {
|
||||
for {
|
||||
relevantReceivedOutputs <- getRelevantOutputs(transaction)
|
||||
action <- processTransactionImpl(
|
||||
action = processTransactionImpl(
|
||||
transaction = transaction,
|
||||
blockHashOpt = blockHashOpt,
|
||||
blockHashWithConfsOpt = blockHashWithConfsOpt,
|
||||
newTags = Vector.empty,
|
||||
receivedSpendingInfoDbsOpt = None,
|
||||
spentSpendingInfoDbsOpt = None,
|
||||
|
@ -187,7 +188,9 @@ case class TransactionProcessing(
|
|||
val spentSpendingInfoDbsF =
|
||||
spendingInfoDAO.findOutputsBeingSpent(block.transactions.toVector)
|
||||
|
||||
val blockHashOpt = Some(block.blockHeader.hash.flip)
|
||||
val blockHash = block.blockHeader.hashBE
|
||||
val blockHashWithConfsOptF: Future[Option[BlockHashWithConfs]] =
|
||||
WalletUtil.getBlockHashWithConfs(chainQueryApi, blockHash)
|
||||
|
||||
// fetch all outputs we may have received in this block in advance
|
||||
// as an optimization
|
||||
|
@ -201,6 +204,7 @@ case class TransactionProcessing(
|
|||
spentSpendingInfoDbs <- spentSpendingInfoDbsF
|
||||
relevantReceivedOutputsForBlock <-
|
||||
relevantReceivedOutputsForBlockF
|
||||
blockHashWithConfsOpt <- blockHashWithConfsOptF
|
||||
} yield {
|
||||
// we need to keep a cache of spentSpendingInfoDb
|
||||
// for the case where we receive & then spend that
|
||||
|
@ -215,10 +219,10 @@ case class TransactionProcessing(
|
|||
_ <- walletF
|
||||
relevantReceivedOutputsForTx = relevantReceivedOutputsForBlock
|
||||
.getOrElse(transaction.txIdBE, Vector.empty)
|
||||
action <-
|
||||
action =
|
||||
processTransactionImpl(
|
||||
transaction = transaction,
|
||||
blockHashOpt = blockHashOpt,
|
||||
blockHashWithConfsOpt = blockHashWithConfsOpt,
|
||||
newTags = Vector.empty,
|
||||
receivedSpendingInfoDbsOpt = receivedSpendingInfoDbsOpt,
|
||||
spentSpendingInfoDbsOpt = cachedSpentOpt,
|
||||
|
@ -314,12 +318,12 @@ case class TransactionProcessing(
|
|||
feeRate: FeeUnit,
|
||||
inputAmount: CurrencyUnit,
|
||||
sentAmount: CurrencyUnit,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE],
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs],
|
||||
newTags: Vector[AddressTag]
|
||||
): Future[ProcessTxResult] = {
|
||||
logger.info(
|
||||
s"Processing TX from our wallet, transaction=${transaction.txIdBE.hex} with blockHash=${blockHashOpt
|
||||
.map(_.hex)}"
|
||||
s"Processing TX from our wallet, transaction=${transaction.txIdBE.hex} with blockHash=${blockHashWithConfsOpt
|
||||
.map(_.blockHash.hex)}"
|
||||
)
|
||||
val relevantOutputsF = getRelevantOutputs(transaction)
|
||||
for {
|
||||
|
@ -329,12 +333,12 @@ case class TransactionProcessing(
|
|||
feeRate,
|
||||
inputAmount,
|
||||
sentAmount,
|
||||
blockHashOpt
|
||||
blockHashWithConfsOpt.map(_.blockHash)
|
||||
)
|
||||
relevantOutputs <- relevantOutputsF
|
||||
action <- processTransactionImpl(
|
||||
action = processTransactionImpl(
|
||||
transaction = txDb.transaction,
|
||||
blockHashOpt = blockHashOpt,
|
||||
blockHashWithConfsOpt = blockHashWithConfsOpt,
|
||||
newTags = newTags,
|
||||
receivedSpendingInfoDbsOpt = None,
|
||||
spentSpendingInfoDbsOpt = None,
|
||||
|
@ -444,48 +448,30 @@ case class TransactionProcessing(
|
|||
*/
|
||||
override def processReceivedUtxos(
|
||||
transaction: Transaction,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE],
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs],
|
||||
spendingInfoDbs: Vector[SpendingInfoDb],
|
||||
newTags: Vector[AddressTag],
|
||||
relevantReceivedOutputs: Vector[OutputWithIndex]
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
val confsOptF: Future[Option[BlockHashWithConfs]] = blockHashOpt match {
|
||||
case Some(blockHash) =>
|
||||
chainQueryApi
|
||||
.getNumberOfConfirmations(blockHash)
|
||||
.map(confsOpt => Some(BlockHashWithConfs(blockHash, confsOpt)))
|
||||
case None => Future.successful(None)
|
||||
}
|
||||
|
||||
val actionF = confsOptF.map { confsOpt =>
|
||||
processReceivedUtxosAction(transaction,
|
||||
confsOpt,
|
||||
spendingInfoDbs,
|
||||
newTags,
|
||||
relevantReceivedOutputs)
|
||||
}
|
||||
actionF.flatMap(a => safeDatabase.run(a))
|
||||
val action = processReceivedUtxosAction(transaction,
|
||||
blockHashWithConfsOpt,
|
||||
spendingInfoDbs,
|
||||
newTags,
|
||||
relevantReceivedOutputs)
|
||||
safeDatabase.run(action)
|
||||
}
|
||||
|
||||
override def processSpentUtxos(
|
||||
transaction: Transaction,
|
||||
outputsBeingSpent: Vector[SpendingInfoDb],
|
||||
blockHashOpt: Option[DoubleSha256DigestBE]
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs]
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
val blockHashWithConfsF: Future[Option[BlockHashWithConfs]] =
|
||||
blockHashOpt match {
|
||||
case Some(blockHash) =>
|
||||
chainQueryApi
|
||||
.getNumberOfConfirmations(blockHash)
|
||||
.map(BlockHashWithConfs(blockHash, _))
|
||||
.map(Some.apply)
|
||||
case None => Future.successful(None)
|
||||
}
|
||||
val actionF = blockHashWithConfsF.map { confsOpt =>
|
||||
processSpentUtxosAction(transaction, outputsBeingSpent, confsOpt)
|
||||
}
|
||||
val action = processSpentUtxosAction(transaction,
|
||||
outputsBeingSpent,
|
||||
blockHashWithConfsOpt)
|
||||
|
||||
actionF.flatMap(safeDatabase.run)
|
||||
safeDatabase.run(action)
|
||||
}
|
||||
|
||||
/** Searches for outputs on the given transaction that are being spent from
|
||||
|
@ -521,17 +507,16 @@ case class TransactionProcessing(
|
|||
*/
|
||||
private[internal] def processTransactionImpl(
|
||||
transaction: Transaction,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE],
|
||||
blockHashWithConfsOpt: Option[BlockHashWithConfs],
|
||||
newTags: Vector[AddressTag],
|
||||
receivedSpendingInfoDbsOpt: Option[Vector[SpendingInfoDb]],
|
||||
spentSpendingInfoDbsOpt: Option[Vector[SpendingInfoDb]],
|
||||
relevantReceivedOutputs: Vector[OutputWithIndex]
|
||||
): Future[
|
||||
DBIOAction[ProcessTxResult, NoStream, Effect.Read & Effect.Write]] = {
|
||||
): DBIOAction[ProcessTxResult, NoStream, Effect.Read & Effect.Write] = {
|
||||
|
||||
logger.debug(
|
||||
s"Processing transaction=${transaction.txIdBE.hex} with blockHash=${blockHashOpt
|
||||
.map(_.hex)}"
|
||||
s"Processing transaction=${transaction.txIdBE.hex} with blockHash=${blockHashWithConfsOpt
|
||||
.map(_.blockHash.hex)}"
|
||||
)
|
||||
val receivedSpendingInfoDbsA
|
||||
: DBIOAction[Vector[SpendingInfoDb], NoStream, Effect.Read] = {
|
||||
|
@ -561,51 +546,43 @@ case class TransactionProcessing(
|
|||
spendingInfoDAO.findOutputsBeingSpentAction(Vector(transaction))
|
||||
}
|
||||
}
|
||||
val confsOptF: Future[Option[BlockHashWithConfs]] = blockHashOpt match {
|
||||
case Some(blockHash) =>
|
||||
chainQueryApi
|
||||
.getNumberOfConfirmations(blockHash)
|
||||
.map(confsOpt => Some(BlockHashWithConfs(blockHash, confsOpt)))
|
||||
case None => Future.successful(None)
|
||||
}
|
||||
val actionF: Future[
|
||||
DBIOAction[ProcessTxResult, NoStream, Effect.Write & Effect.Read]] =
|
||||
confsOptF.map { confsOpt =>
|
||||
for {
|
||||
receivedSpendingInfoDbs <- receivedSpendingInfoDbsA
|
||||
receivedStart = TimeUtil.currentEpochMs
|
||||
incoming <- processReceivedUtxosAction(
|
||||
transaction = transaction,
|
||||
blockHashWithConfsOpt = confsOpt,
|
||||
spendingInfoDbs = receivedSpendingInfoDbs,
|
||||
newTags = newTags,
|
||||
relevantReceivedOutputs = relevantReceivedOutputs
|
||||
val action
|
||||
: DBIOAction[ProcessTxResult, NoStream, Effect.Write & Effect.Read] =
|
||||
for {
|
||||
receivedSpendingInfoDbs <- receivedSpendingInfoDbsA
|
||||
receivedStart = TimeUtil.currentEpochMs
|
||||
incoming <- processReceivedUtxosAction(
|
||||
transaction = transaction,
|
||||
blockHashWithConfsOpt = blockHashWithConfsOpt,
|
||||
spendingInfoDbs = receivedSpendingInfoDbs,
|
||||
newTags = newTags,
|
||||
relevantReceivedOutputs = relevantReceivedOutputs
|
||||
)
|
||||
_ = if (incoming.nonEmpty) {
|
||||
logger.info(
|
||||
s"Finished processing ${incoming.length} received outputs, balance=${incoming
|
||||
.map(_.output.value)
|
||||
.sum} it took=${TimeUtil.currentEpochMs - receivedStart}ms"
|
||||
)
|
||||
_ = if (incoming.nonEmpty) {
|
||||
logger.info(
|
||||
s"Finished processing ${incoming.length} received outputs, balance=${incoming
|
||||
.map(_.output.value)
|
||||
.sum} it took=${TimeUtil.currentEpochMs - receivedStart}ms"
|
||||
)
|
||||
}
|
||||
|
||||
spentSpendingInfoDbs <- spentSpendingInfoDbsF
|
||||
spentStart = TimeUtil.currentEpochMs
|
||||
outgoing <- processSpentUtxosAction(
|
||||
transaction = transaction,
|
||||
outputsBeingSpent = spentSpendingInfoDbs,
|
||||
blockHashWithConfs = confsOpt
|
||||
)
|
||||
_ = if (outgoing.nonEmpty) {
|
||||
logger.info(
|
||||
s"Finished processing ${outgoing.length} spent outputs, it took=${TimeUtil.currentEpochMs - spentStart}ms"
|
||||
)
|
||||
}
|
||||
} yield {
|
||||
ProcessTxResult(incoming, outgoing)
|
||||
}
|
||||
|
||||
spentSpendingInfoDbs <- spentSpendingInfoDbsF
|
||||
spentStart = TimeUtil.currentEpochMs
|
||||
outgoing <- processSpentUtxosAction(
|
||||
transaction = transaction,
|
||||
outputsBeingSpent = spentSpendingInfoDbs,
|
||||
blockHashWithConfs = blockHashWithConfsOpt
|
||||
)
|
||||
_ = if (outgoing.nonEmpty) {
|
||||
logger.info(
|
||||
s"Finished processing ${outgoing.length} spent outputs, it took=${TimeUtil.currentEpochMs - spentStart}ms"
|
||||
)
|
||||
}
|
||||
} yield {
|
||||
ProcessTxResult(incoming, outgoing)
|
||||
}
|
||||
actionF
|
||||
|
||||
action
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.bitcoins.db.SafeDatabase
|
|||
import org.bitcoins.wallet.callback.WalletCallbacks
|
||||
import org.bitcoins.wallet.config.WalletAppConfig
|
||||
import org.bitcoins.wallet.models.{AddressDAO, SpendingInfoDAO, TransactionDAO}
|
||||
import org.bitcoins.wallet.util.WalletUtil
|
||||
import slick.dbio.{DBIOAction, Effect, NoStream}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
@ -258,9 +259,8 @@ case class UtxoHandling(
|
|||
case (blockHashOpt, spendingInfoDbs) =>
|
||||
blockHashOpt match {
|
||||
case Some(blockHash) =>
|
||||
chainQueryApi
|
||||
.getNumberOfConfirmations(blockHash)
|
||||
.map(confs => Some(BlockHashWithConfs(blockHash, confs)))
|
||||
WalletUtil
|
||||
.getBlockHashWithConfs(chainQueryApi, blockHash)
|
||||
.map(blockWithConfsOpt => (blockWithConfsOpt, spendingInfoDbs))
|
||||
case None =>
|
||||
Future.successful((None, spendingInfoDbs))
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package org.bitcoins.wallet.util
|
||||
|
||||
import org.bitcoins.core.api.chain.ChainQueryApi
|
||||
import org.bitcoins.core.util.BlockHashWithConfs
|
||||
import org.bitcoins.crypto.DoubleSha256DigestBE
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
object WalletUtil {
|
||||
|
||||
def getBlockHashWithConfs(
|
||||
chainQueryApi: ChainQueryApi,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE])(implicit
|
||||
ec: ExecutionContext): Future[Option[BlockHashWithConfs]] = {
|
||||
blockHashOpt match {
|
||||
case Some(blockHash) =>
|
||||
chainQueryApi
|
||||
.getNumberOfConfirmations(blockHash)
|
||||
.map(confsOpt => Some(BlockHashWithConfs(blockHash, confsOpt)))
|
||||
case None => Future.successful(None)
|
||||
}
|
||||
}
|
||||
|
||||
def getBlockHashWithConfs(
|
||||
chainQueryApi: ChainQueryApi,
|
||||
blockHash: DoubleSha256DigestBE)(implicit
|
||||
ec: ExecutionContext): Future[Option[BlockHashWithConfs]] = {
|
||||
getBlockHashWithConfs(chainQueryApi, Some(blockHash))
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue