wallet: Get processBlockCachedUtxos() using DBIOAction (#5740)

* wallet: Get processBlockCachedUtxos() using DBIOAction

* Remove unused val
This commit is contained in:
Chris Stewart 2024-10-29 06:00:57 -05:00 committed by GitHub
parent 2366b80c70
commit 3ae69b6ab5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -179,15 +179,11 @@ case class TransactionProcessing(
// fetch all received spending info dbs relevant to txs in this block to improve performance // fetch all received spending info dbs relevant to txs in this block to improve performance
val receivedSpendingInfoDbsF = val receivedSpendingInfoDbsF =
spendingInfoDAO spendingInfoDAO
.findTxs(block.transactions.toVector) .findTxs(block.transactions)
val cachedReceivedOptF = receivedSpendingInfoDbsF val cachedReceivedOptF = receivedSpendingInfoDbsF
.map(Some(_)) // reduce allocations by creating Some here .map(Some(_)) // reduce allocations by creating Some here
// fetch all spending infoDbs for this block to improve performance
val spentSpendingInfoDbsF =
spendingInfoDAO.findOutputsBeingSpent(block.transactions.toVector)
val blockHash = block.blockHeader.hashBE val blockHash = block.blockHeader.hashBE
val blockHashWithConfsOptF: Future[Option[BlockHashWithConfs]] = val blockHashWithConfsOptF: Future[Option[BlockHashWithConfs]] =
WalletUtil.getBlockHashWithConfs(chainQueryApi, blockHash) WalletUtil.getBlockHashWithConfs(chainQueryApi, blockHash)
@ -196,71 +192,42 @@ case class TransactionProcessing(
// as an optimization // as an optimization
val relevantReceivedOutputsForBlockF = getRelevantOutputsForBlock(block) val relevantReceivedOutputsForBlockF = getRelevantOutputsForBlock(block)
val resultF: Future[Future[Unit]] = for { val actionsF: Future[Vector[
// map on these first so we don't have to call DBIOAction[ProcessTxResult, NoStream, Effect.Read & Effect.Write]]] =
// .map everytime we iterate through a tx for {
// which is costly (thread overhead) // map on these first so we don't have to call
receivedSpendingInfoDbsOpt <- cachedReceivedOptF // .map everytime we iterate through a tx
spentSpendingInfoDbs <- spentSpendingInfoDbsF // which is costly (thread overhead)
relevantReceivedOutputsForBlock <- receivedSpendingInfoDbsOpt <- cachedReceivedOptF
relevantReceivedOutputsForBlockF relevantReceivedOutputsForBlock <-
blockHashWithConfsOpt <- blockHashWithConfsOptF relevantReceivedOutputsForBlockF
} yield { blockHashWithConfsOpt <- blockHashWithConfsOptF
// we need to keep a cache of spentSpendingInfoDb actions = {
// for the case where we receive & then spend that block.transactions.map { transaction =>
// same utxo in the same block val relevantReceivedOutputsForTx = relevantReceivedOutputsForBlock
var cachedSpentOpt: Option[Vector[SpendingInfoDb]] = {
Some(spentSpendingInfoDbs)
}
val blockInputs = block.transactions.flatMap(_.inputs)
val processedF: Future[Unit] = {
block.transactions.foldLeft(Future.unit) { (walletF, transaction) =>
for {
_ <- walletF
relevantReceivedOutputsForTx = relevantReceivedOutputsForBlock
.getOrElse(transaction.txIdBE, Vector.empty) .getOrElse(transaction.txIdBE, Vector.empty)
action = for {
processTransactionImpl( action <-
transaction = transaction, processTransactionImpl(
blockHashWithConfsOpt = blockHashWithConfsOpt, transaction = transaction,
newTags = Vector.empty, blockHashWithConfsOpt = blockHashWithConfsOpt,
receivedSpendingInfoDbsOpt = receivedSpendingInfoDbsOpt, newTags = Vector.empty,
spentSpendingInfoDbsOpt = cachedSpentOpt, receivedSpendingInfoDbsOpt = receivedSpendingInfoDbsOpt,
relevantReceivedOutputs = relevantReceivedOutputsForTx spentSpendingInfoDbsOpt = None,
) relevantReceivedOutputs = relevantReceivedOutputsForTx
)
processTxResult <- safeDatabase.run(action) } yield {
_ = { action
// need to look if a received utxo is spent in the same block
// if so, we need to update our cachedSpentF
val spentInSameBlock: Vector[SpendingInfoDb] = {
processTxResult.updatedIncoming.filter { spendingInfoDb =>
blockInputs.exists(
_.previousOutput == spendingInfoDb.outPoint
)
}
}
// add it to the cache
val newCachedSpentOpt = {
cachedSpentOpt match {
case Some(spentSpendingInfo) =>
Some(spentSpendingInfo ++ spentInSameBlock)
case None =>
Some(spentInSameBlock)
}
}
cachedSpentOpt = newCachedSpentOpt
} }
} yield {
()
} }
} }
} yield {
actions
} }
processedF
}
resultF.flatten actionsF
.flatMap(actions => Future.sequence(actions.map(safeDatabase.run)))
.map(_ => ())
} }
override def findTransaction( override def findTransaction(