mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
refactor: Move more methods out of WalletApi (#5681)
Remove more methods out of WalletApi refactor: move getTransactionsToBroadcast to SendFundsHandlingApi
This commit is contained in:
parent
58e2dc2b5a
commit
7caea21b6a
@ -18,6 +18,7 @@ import org.bitcoins.core.api.wallet.{
|
||||
FundTransactionHandlingApi,
|
||||
RescanHandlingApi,
|
||||
SendFundsHandlingApi,
|
||||
TransactionProcessingApi,
|
||||
UtxoHandlingApi
|
||||
}
|
||||
import org.bitcoins.core.config.RegTest
|
||||
@ -104,6 +105,9 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
|
||||
val mockAddressHandlingApi: AddressHandlingApi = mock[AddressHandlingApi]
|
||||
|
||||
val mockTransactionProcessingApi: TransactionProcessingApi =
|
||||
mock[TransactionProcessingApi]
|
||||
|
||||
val mockFundTxHandlingApi: FundTransactionHandlingApi =
|
||||
mock[FundTransactionHandlingApi]
|
||||
|
||||
@ -453,6 +457,12 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
val spendingInfoDb = TransactionTestUtil.spendingInfoDb
|
||||
|
||||
"return the wallet's balances in bitcoin" in {
|
||||
|
||||
(() => mockWalletApi.utxoHandling)
|
||||
.expects()
|
||||
.returning(mockUtxoHandlingApi)
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(() => mockWalletApi.getConfirmedBalance())
|
||||
.expects()
|
||||
.returning(Future.successful(Bitcoins(50)))
|
||||
@ -461,7 +471,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
.expects()
|
||||
.returning(Future.successful(Bitcoins(50)))
|
||||
|
||||
(mockWalletApi
|
||||
(mockWalletApi.utxoHandling
|
||||
.listUtxos(_: TxoState))
|
||||
.expects(TxoState.Reserved)
|
||||
.returning(Future.successful(Vector(spendingInfoDb)))
|
||||
@ -488,7 +498,12 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
.expects()
|
||||
.returning(Future.successful(Bitcoins(50)))
|
||||
|
||||
(mockWalletApi
|
||||
(() => mockWalletApi.utxoHandling)
|
||||
.expects()
|
||||
.returning(mockUtxoHandlingApi)
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(mockWalletApi.utxoHandling
|
||||
.listUtxos(_: TxoState))
|
||||
.expects(TxoState.Reserved)
|
||||
.returning(Future.successful(Vector(spendingInfoDb)))
|
||||
@ -537,8 +552,12 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
}
|
||||
|
||||
"return the wallet utxos" in {
|
||||
(() => mockWalletApi.utxoHandling)
|
||||
.expects()
|
||||
.returning(mockUtxoHandlingApi)
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(() => mockWalletApi.listUtxos())
|
||||
(() => mockWalletApi.utxoHandling.listUtxos())
|
||||
.expects()
|
||||
.returning(Future.successful(Vector(spendingInfoDb)))
|
||||
|
||||
@ -554,8 +573,11 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
}
|
||||
|
||||
"return the reserved wallet utxos" in {
|
||||
|
||||
(mockWalletApi
|
||||
(() => mockWalletApi.utxoHandling)
|
||||
.expects()
|
||||
.returning(mockUtxoHandlingApi)
|
||||
.anyNumberOfTimes()
|
||||
(mockWalletApi.utxoHandling
|
||||
.listUtxos(_: TxoState))
|
||||
.expects(TxoState.Reserved)
|
||||
.returning(Future.successful(Vector(spendingInfoDb)))
|
||||
@ -799,24 +821,34 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
}
|
||||
|
||||
"lock unspent" in {
|
||||
(() => mockWalletApi.listUtxos())
|
||||
(() => mockWalletApi.utxoHandling)
|
||||
.expects()
|
||||
.returning(mockUtxoHandlingApi)
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(() => mockWalletApi.utxoHandling.listUtxos())
|
||||
.expects()
|
||||
.returning(Future.successful(Vector(spendingInfoDb)))
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(mockWalletApi
|
||||
(mockWalletApi.utxoHandling
|
||||
.listUtxos(_: TxoState))
|
||||
.expects(TxoState.Reserved)
|
||||
.returning(Future.successful(Vector(spendingInfoDb)))
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(mockWalletApi
|
||||
(() => mockWalletApi.utxoHandling)
|
||||
.expects()
|
||||
.returning(mockUtxoHandlingApi)
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(mockWalletApi.utxoHandling
|
||||
.markUTXOsAsReserved(_: Vector[SpendingInfoDb]))
|
||||
.expects(Vector(spendingInfoDb))
|
||||
.returning(Future.successful(Vector(spendingInfoDb)))
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(mockWalletApi
|
||||
(mockWalletApi.utxoHandling
|
||||
.unmarkUTXOsAsReserved(_: Vector[SpendingInfoDb]))
|
||||
.expects(Vector(spendingInfoDb))
|
||||
.returning(Future.successful(Vector(spendingInfoDb)))
|
||||
@ -1116,7 +1148,12 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
|
||||
val txDb = TransactionDbHelper.fromTransaction(tx, None)
|
||||
|
||||
(mockWalletApi
|
||||
(() => mockWalletApi.transactionProcessing)
|
||||
.expects()
|
||||
.returning(mockTransactionProcessingApi)
|
||||
.anyNumberOfTimes()
|
||||
|
||||
(mockWalletApi.transactionProcessing
|
||||
.findByTxIds(_: Vector[DoubleSha256DigestBE]))
|
||||
.expects(Vector(tx.txIdBE))
|
||||
.returning(Future.successful(Vector(txDb)))
|
||||
|
@ -620,7 +620,7 @@ class BitcoinSServerMain(override val serverArgParser: ServerArgParser)(implicit
|
||||
wallet,
|
||||
chainCallbacksOpt
|
||||
)(system)
|
||||
_ = syncF.map(_ => wallet.updateUtxoPendingStates())
|
||||
_ = syncF.map(_ => wallet.utxoHandling.updateUtxoPendingStates())
|
||||
|
||||
// don't start polling until initial sync is done
|
||||
pollingCancellable <- syncF.flatMap { _ =>
|
||||
|
@ -102,7 +102,7 @@ object BitcoindRpcBackendUtil extends BitcoinSLogger {
|
||||
bitcoindHeight: Int
|
||||
)(implicit ex: ExecutionContext): Future[Range.Inclusive] = {
|
||||
for {
|
||||
txDbs <- wallet.listTransactions()
|
||||
txDbs <- wallet.transactionProcessing.listTransactions()
|
||||
lastConfirmedOpt = txDbs
|
||||
.filter(_.blockHashOpt.isDefined)
|
||||
.lastOption
|
||||
@ -391,7 +391,7 @@ object BitcoindRpcBackendUtil extends BitcoinSLogger {
|
||||
for {
|
||||
_ <- doneF
|
||||
w <- walletF
|
||||
_ <- w.updateUtxoPendingStates()
|
||||
_ <- w.utxoHandling.updateUtxoPendingStates()
|
||||
} yield ()
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
for {
|
||||
confirmed <- wallet.getConfirmedBalance()
|
||||
unconfirmed <- wallet.getUnconfirmedBalance()
|
||||
reservedUtxos <- wallet.listUtxos(TxoState.Reserved)
|
||||
reservedUtxos <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
} yield {
|
||||
|
||||
val reserved = reservedUtxos.map(_.output.value).sum
|
||||
@ -189,7 +189,7 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
withValidServerCommand(GetTransaction.fromJsArr(arr)) {
|
||||
case GetTransaction(txId) =>
|
||||
complete {
|
||||
val resultF = wallet.findByTxId(txId).map {
|
||||
val resultF = wallet.transactionProcessing.findByTxId(txId).map {
|
||||
case None =>
|
||||
Server.httpSuccess(ujson.Null)
|
||||
case Some(txDb) =>
|
||||
@ -206,15 +206,15 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
complete {
|
||||
val func: Vector[SpendingInfoDb] => Future[Vector[SpendingInfoDb]] =
|
||||
utxos => {
|
||||
if (unlock) wallet.unmarkUTXOsAsReserved(utxos)
|
||||
else wallet.markUTXOsAsReserved(utxos)
|
||||
if (unlock) wallet.utxoHandling.unmarkUTXOsAsReserved(utxos)
|
||||
else wallet.utxoHandling.markUTXOsAsReserved(utxos)
|
||||
}
|
||||
|
||||
for {
|
||||
utxos <-
|
||||
if (unlock) {
|
||||
wallet.listUtxos(TxoState.Reserved)
|
||||
} else wallet.listUtxos()
|
||||
wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
} else wallet.utxoHandling.listUtxos()
|
||||
|
||||
filtered =
|
||||
if (outputParams.nonEmpty) {
|
||||
@ -794,7 +794,7 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
|
||||
case ServerCommand("getutxos", _) =>
|
||||
complete {
|
||||
wallet.listUtxos().map { utxos =>
|
||||
wallet.utxoHandling.listUtxos().map { utxos =>
|
||||
val json = utxos.map(spendingInfoDbToJson)
|
||||
Server.httpSuccess(json)
|
||||
}
|
||||
@ -802,7 +802,7 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
|
||||
case ServerCommand("listreservedutxos", _) =>
|
||||
complete {
|
||||
wallet.listUtxos(TxoState.Reserved).map { utxos =>
|
||||
wallet.utxoHandling.listUtxos(TxoState.Reserved).map { utxos =>
|
||||
val json = utxos.map(spendingInfoDbToJson)
|
||||
Server.httpSuccess(json)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ object CallbackUtil extends BitcoinSLogger {
|
||||
if (headers.isEmpty) {
|
||||
Future.unit
|
||||
} else {
|
||||
wallet.updateUtxoPendingStates().map(_ => ())
|
||||
wallet.utxoHandling.updateUtxoPendingStates().map(_ => ())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,11 @@ trait AddressHandlingApi {
|
||||
address: BitcoinAddress,
|
||||
tagType: AddressTagType
|
||||
): Future[Vector[AddressTagDb]]
|
||||
|
||||
/** Determines if the given output is from this wallet and is a change output
|
||||
* from this wallet
|
||||
*/
|
||||
def isChange(output: TransactionOutput): Future[Boolean]
|
||||
def listAddresses(): Future[Vector[AddressDb]]
|
||||
def listUnusedAddresses(): Future[Vector[AddressDb]]
|
||||
def listScriptPubKeys(): Future[Vector[ScriptPubKeyDb]]
|
||||
|
@ -29,7 +29,7 @@ trait SendFundsHandlingApi {
|
||||
def bumpFeeCPFP(
|
||||
txId: DoubleSha256DigestBE,
|
||||
feeRate: FeeUnit): Future[Transaction]
|
||||
|
||||
def getTransactionsToBroadcast: Future[Vector[Transaction]]
|
||||
def makeOpReturnCommitment(
|
||||
message: String,
|
||||
hashMessage: Boolean,
|
||||
|
@ -6,11 +6,24 @@ import org.bitcoins.core.protocol.blockchain.Block
|
||||
import org.bitcoins.core.protocol.transaction.{OutputWithIndex, Transaction}
|
||||
import org.bitcoins.core.wallet.fee.FeeUnit
|
||||
import org.bitcoins.core.wallet.utxo.AddressTag
|
||||
import org.bitcoins.crypto.DoubleSha256DigestBE
|
||||
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
trait TransactionProcessingApi {
|
||||
def findByTxIds(
|
||||
txIds: Vector[DoubleSha256DigestBE]): Future[Vector[TransactionDb]]
|
||||
final def findByTxId(txId: DoubleSha256DigestBE)(implicit
|
||||
ec: ExecutionContext): Future[Option[TransactionDb]] = {
|
||||
findByTxIds(Vector(txId)).map(_.headOption)
|
||||
}
|
||||
final def findByTxId(txId: DoubleSha256Digest)(implicit
|
||||
ec: ExecutionContext): Future[Option[TransactionDb]] = {
|
||||
findByTxId(txId.flip)
|
||||
}
|
||||
|
||||
def listTransactions(): Future[Vector[TransactionDb]]
|
||||
|
||||
def processTransaction(
|
||||
transaction: Transaction,
|
||||
blockHashOpt: Option[DoubleSha256DigestBE]
|
||||
@ -32,7 +45,6 @@ trait TransactionProcessingApi {
|
||||
def findTransaction(
|
||||
txId: DoubleSha256DigestBE
|
||||
): Future[Option[TransactionDb]]
|
||||
def listTransactions(): Future[Vector[TransactionDb]]
|
||||
|
||||
def subscribeForBlockProcessingCompletionSignal(
|
||||
blockHash: DoubleSha256DigestBE
|
||||
|
@ -1,11 +1,13 @@
|
||||
package org.bitcoins.core.api.wallet
|
||||
|
||||
import org.bitcoins.core.api.wallet.db.SpendingInfoDb
|
||||
import org.bitcoins.core.currency.CurrencyUnit
|
||||
import org.bitcoins.core.hd.HDAccount
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionOutPoint}
|
||||
import org.bitcoins.core.wallet.utxo.{AddressTag, TxoState}
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
trait UtxoHandlingApi {
|
||||
|
||||
@ -16,6 +18,33 @@ trait UtxoHandlingApi {
|
||||
|
||||
def clearAllAddresses(): Future[Unit]
|
||||
|
||||
/** Finds all the outputs in our wallet being spent in the given transaction
|
||||
*/
|
||||
def findOutputsBeingSpent(tx: Transaction): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def findByScriptPubKey(
|
||||
scriptPubKey: ScriptPubKey): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def findByOutPoints(
|
||||
outPoints: Vector[TransactionOutPoint]): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
final def findByOutPoint(outPoint: TransactionOutPoint)(implicit
|
||||
ec: ExecutionContext): Future[Option[SpendingInfoDb]] = {
|
||||
findByOutPoints(Vector(outPoint)).map(_.headOption)
|
||||
}
|
||||
|
||||
def getUnconfirmedBalance(tag: AddressTag): Future[CurrencyUnit]
|
||||
def getConfirmedBalance(tag: AddressTag): Future[CurrencyUnit]
|
||||
final def getBalance(tag: AddressTag)(implicit
|
||||
ec: ExecutionContext): Future[CurrencyUnit] = {
|
||||
val uF = getUnconfirmedBalance(tag)
|
||||
val cF = getConfirmedBalance(tag)
|
||||
for {
|
||||
u <- uF
|
||||
c <- cF
|
||||
} yield u + c
|
||||
}
|
||||
|
||||
def listDefaultAccountUtxos(): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
/** Lists unspent transaction outputs in the wallet
|
||||
|
@ -3,21 +3,14 @@ package org.bitcoins.core.api.wallet
|
||||
import org.bitcoins.core.api.chain.ChainQueryApi
|
||||
import org.bitcoins.core.api.feeprovider.FeeRateApi
|
||||
import org.bitcoins.core.api.node.NodeApi
|
||||
import org.bitcoins.core.api.wallet.db.*
|
||||
import org.bitcoins.core.crypto.ExtPublicKey
|
||||
import org.bitcoins.core.currency.CurrencyUnit
|
||||
import org.bitcoins.core.hd.HDAccount
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.transaction.{
|
||||
Transaction,
|
||||
TransactionOutPoint,
|
||||
TransactionOutput
|
||||
}
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.core.util.StartStopAsync
|
||||
import org.bitcoins.core.wallet.fee.FeeUnit
|
||||
import org.bitcoins.core.wallet.utxo.{AddressTag, TxoState}
|
||||
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
|
||||
import org.bitcoins.crypto.DoubleSha256DigestBE
|
||||
|
||||
import java.time.Instant
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
@ -46,8 +39,6 @@ trait WalletApi extends StartStopAsync[WalletApi] {
|
||||
def broadcastTransaction(transaction: Transaction): Future[Unit] =
|
||||
nodeApi.broadcastTransaction(transaction)
|
||||
|
||||
def getTransactionsToBroadcast: Future[Vector[Transaction]]
|
||||
|
||||
def getFeeRate(): Future[FeeUnit] = feeRateApi.getFeeRate()
|
||||
|
||||
def start(): Future[WalletApi]
|
||||
@ -65,23 +56,9 @@ trait WalletApi extends StartStopAsync[WalletApi] {
|
||||
} yield confirmed + unconfirmed
|
||||
}
|
||||
|
||||
/** Gets the sum of all UTXOs in this wallet with the address tag */
|
||||
def getBalance(tag: AddressTag)(implicit
|
||||
ec: ExecutionContext): Future[CurrencyUnit] = {
|
||||
val confirmedF = getConfirmedBalance(tag)
|
||||
val unconfirmedF = getUnconfirmedBalance(tag)
|
||||
|
||||
for {
|
||||
confirmed <- confirmedF
|
||||
unconfirmed <- unconfirmedF
|
||||
} yield confirmed + unconfirmed
|
||||
}
|
||||
|
||||
/** Gets the sum of all confirmed UTXOs in this wallet */
|
||||
def getConfirmedBalance(): Future[CurrencyUnit]
|
||||
|
||||
def getConfirmedBalance(tag: AddressTag): Future[CurrencyUnit]
|
||||
|
||||
def getNewAddress(): Future[BitcoinAddress]
|
||||
|
||||
def getNewChangeAddress(): Future[BitcoinAddress]
|
||||
@ -89,32 +66,9 @@ trait WalletApi extends StartStopAsync[WalletApi] {
|
||||
/** Gets the sum of all unconfirmed UTXOs in this wallet */
|
||||
def getUnconfirmedBalance(): Future[CurrencyUnit]
|
||||
|
||||
def getUnconfirmedBalance(tag: AddressTag): Future[CurrencyUnit]
|
||||
|
||||
def listTransactions(): Future[Vector[TransactionDb]]
|
||||
|
||||
def listUtxos(): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def listUtxos(state: TxoState): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def listUtxos(tag: AddressTag): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
/** Checks if the wallet contains any data */
|
||||
def isEmpty(): Future[Boolean]
|
||||
|
||||
protected def determineFeeRate(feeRateOpt: Option[FeeUnit]): Future[FeeUnit] =
|
||||
feeRateOpt match {
|
||||
case None =>
|
||||
feeRateApi.getFeeRate()
|
||||
case Some(feeRate) =>
|
||||
Future.successful(feeRate)
|
||||
}
|
||||
|
||||
/** Determines if the given output is from this wallet and is a change output
|
||||
* from this wallet
|
||||
*/
|
||||
def isChange(output: TransactionOutput): Future[Boolean]
|
||||
|
||||
def getSyncState(): Future[BlockSyncState]
|
||||
|
||||
def isRescanning(): Future[Boolean]
|
||||
@ -124,54 +78,6 @@ trait WalletApi extends StartStopAsync[WalletApi] {
|
||||
def getWalletName(): Future[String]
|
||||
|
||||
def getInfo(): Future[WalletInfo]
|
||||
|
||||
def findByOutPoints(
|
||||
outPoints: Vector[TransactionOutPoint]): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def findByOutPoint(outPoint: TransactionOutPoint)(implicit
|
||||
ec: ExecutionContext): Future[Option[SpendingInfoDb]] = {
|
||||
findByOutPoints(Vector(outPoint)).map(_.headOption)
|
||||
}
|
||||
|
||||
def findByTxIds(
|
||||
txIds: Vector[DoubleSha256DigestBE]): Future[Vector[TransactionDb]]
|
||||
|
||||
def findByTxId(txId: DoubleSha256DigestBE)(implicit
|
||||
ec: ExecutionContext): Future[Option[TransactionDb]] = {
|
||||
findByTxIds(Vector(txId)).map(_.headOption)
|
||||
}
|
||||
|
||||
def findByTxId(txId: DoubleSha256Digest)(implicit
|
||||
ec: ExecutionContext): Future[Option[TransactionDb]] = {
|
||||
findByTxId(txId.flip)
|
||||
}
|
||||
|
||||
/** Finds all the outputs in our wallet being spent in the given transaction
|
||||
*/
|
||||
def findOutputsBeingSpent(tx: Transaction): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def findByScriptPubKey(
|
||||
scriptPubKey: ScriptPubKey): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
/** Takes in a block header and updates our TxoStates to the new chain tip
|
||||
* @param blockHeader
|
||||
* Block header we are processing
|
||||
*/
|
||||
def updateUtxoPendingStates(): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def markUTXOsAsReserved(
|
||||
utxos: Vector[SpendingInfoDb]): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
/** Marks all utxos that are ours in this transactions as reserved */
|
||||
def markUTXOsAsReserved(tx: Transaction): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
def unmarkUTXOsAsReserved(
|
||||
utxos: Vector[SpendingInfoDb]): Future[Vector[SpendingInfoDb]]
|
||||
|
||||
/** Unmarks all utxos that are ours in this transactions indicating they are
|
||||
* no longer reserved
|
||||
*/
|
||||
def unmarkUTXOsAsReserved(tx: Transaction): Future[Vector[SpendingInfoDb]]
|
||||
}
|
||||
|
||||
case class WalletInfo(
|
||||
|
@ -92,8 +92,8 @@ class MultiWalletDLCTest extends BitcoinSWalletTest {
|
||||
// now unreserve the utxo
|
||||
val reservedUtxoF = for {
|
||||
_ <- offerF
|
||||
utxos <- wallet.listUtxos(TxoState.Reserved)
|
||||
_ <- wallet.unmarkUTXOsAsReserved(utxos)
|
||||
utxos <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
_ <- wallet.utxoHandling.unmarkUTXOsAsReserved(utxos)
|
||||
} yield ()
|
||||
|
||||
// now cancel the offer
|
||||
|
@ -25,7 +25,7 @@ import org.bitcoins.core.wallet.builder.{
|
||||
FundRawTxHelper,
|
||||
ShufflingNonInteractiveFinalizer
|
||||
}
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
|
||||
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerVirtualByte}
|
||||
import org.bitcoins.core.wallet.utxo.*
|
||||
import org.bitcoins.crypto.*
|
||||
import org.bitcoins.db.SafeDatabase
|
||||
@ -2247,6 +2247,14 @@ abstract class DLCWallet
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private def determineFeeRate(feeRateOpt: Option[FeeUnit]): Future[FeeUnit] =
|
||||
feeRateOpt match {
|
||||
case None =>
|
||||
feeRateApi.getFeeRate()
|
||||
case Some(feeRate) =>
|
||||
Future.successful(feeRate)
|
||||
}
|
||||
}
|
||||
|
||||
object DLCWallet extends WalletLogger {
|
||||
|
@ -66,6 +66,12 @@ case class DLCTransactionProcessing(
|
||||
dlcWalletDAOs.dlcAnnouncementDAO
|
||||
private lazy val safeDLCDatabase: SafeDatabase = dlcDAO.safeDatabase
|
||||
|
||||
override def findByTxIds(
|
||||
txIds: Vector[DoubleSha256DigestBE]
|
||||
): Future[Vector[TransactionDb]] = {
|
||||
transactionDAO.findByTxIds(txIds)
|
||||
}
|
||||
|
||||
/** Calculates the new state of the DLCDb based on the closing transaction,
|
||||
* will delete old CET sigs that are no longer needed after execution
|
||||
* @return
|
||||
|
@ -124,7 +124,7 @@ class NeutrinoNodeWithWalletTest extends NodeTestWithCachedBitcoindNewest {
|
||||
maxTries = 30
|
||||
)
|
||||
// assert we got the full tx with witness data
|
||||
txs <- wallet.listTransactions()
|
||||
txs <- wallet.transactionProcessing.listTransactions()
|
||||
} yield assert(txs.exists(_.transaction == expectedTx))
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ class NeutrinoNodeWithWalletTest extends NodeTestWithCachedBitcoindNewest {
|
||||
_ <- generateBlock()
|
||||
|
||||
// verify
|
||||
txs <- wallet.listTransactions()
|
||||
txs <- wallet.transactionProcessing.listTransactions()
|
||||
} yield assert(txs.exists(_.txIdBE == txSent.txIdBE))
|
||||
}
|
||||
|
||||
|
@ -256,12 +256,12 @@ class AddressHandlingTest extends BitcoinSWalletTest {
|
||||
for {
|
||||
nonChange <- wallet.getNewAddress()
|
||||
output0 = TransactionOutput(Satoshis.zero, nonChange.scriptPubKey)
|
||||
res0 <- wallet.isChange(output0)
|
||||
res0 <- wallet.addressHandling.isChange(output0)
|
||||
_ = assert(!res0)
|
||||
|
||||
change <- wallet.getNewChangeAddress()
|
||||
output1 = TransactionOutput(Satoshis.zero, change.scriptPubKey)
|
||||
res1 <- wallet.isChange(output1)
|
||||
res1 <- wallet.addressHandling.isChange(output1)
|
||||
} yield assert(res1)
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class AddressTagIntegrationTest extends BitcoinSWalletTest {
|
||||
tx <- bitcoind.getRawTransactionRaw(txId)
|
||||
|
||||
// before processing TX, wallet should be completely empty
|
||||
_ <- wallet.listUtxos().map(utxos => assert(utxos.isEmpty))
|
||||
_ <- wallet.utxoHandling.listUtxos().map(utxos => assert(utxos.isEmpty))
|
||||
_ <- wallet.getBalance().map(confirmed => assert(confirmed == 0.bitcoin))
|
||||
_ <-
|
||||
wallet
|
||||
@ -60,7 +60,7 @@ class AddressTagIntegrationTest extends BitcoinSWalletTest {
|
||||
|
||||
// we should now have one UTXO in the wallet
|
||||
// it should not be confirmed
|
||||
utxosPostAdd <- wallet.listUtxos()
|
||||
utxosPostAdd <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(utxosPostAdd.length == 2)
|
||||
_ <-
|
||||
wallet
|
||||
@ -74,10 +74,10 @@ class AddressTagIntegrationTest extends BitcoinSWalletTest {
|
||||
_ = assert(incomingTx.isDefined)
|
||||
_ = assert(incomingTx.get.incomingAmount == valueFromBitcoind * 2)
|
||||
|
||||
taggedUtxosPostAdd <- wallet.listUtxos(exampleTag)
|
||||
taggedUtxosPostAdd <- wallet.utxoHandling.listUtxos(exampleTag)
|
||||
_ = assert(taggedUtxosPostAdd.length == 1)
|
||||
_ <-
|
||||
wallet
|
||||
wallet.utxoHandling
|
||||
.getUnconfirmedBalance(exampleTag)
|
||||
.map(unconfirmed => assert(unconfirmed == valueFromBitcoind))
|
||||
|
||||
@ -95,9 +95,9 @@ class AddressTagIntegrationTest extends BitcoinSWalletTest {
|
||||
signedTx = rawTxHelper.signedTx
|
||||
_ <- wallet.transactionProcessing.processTransaction(signedTx, None)
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
balancePostSend <- wallet.getBalance()
|
||||
tagBalancePostSend <- wallet.getBalance(exampleTag)
|
||||
tagBalancePostSend <- wallet.utxoHandling.getBalance(exampleTag)
|
||||
} yield {
|
||||
// One change one external
|
||||
assert(utxos.size == 2)
|
||||
|
@ -109,7 +109,7 @@ class BitcoindBackendTest extends WalletAppConfigWithBitcoindNewestFixtures {
|
||||
|
||||
_ <- BitcoindRpcBackendUtil.syncWalletToBitcoind(bitcoind, wallet, None)
|
||||
|
||||
utxos <- wallet.listUtxos(TxoState.ConfirmedReceived)
|
||||
utxos <- wallet.utxoHandling.listUtxos(TxoState.ConfirmedReceived)
|
||||
} yield {
|
||||
assert(utxos.size == 1)
|
||||
val utxo = utxos.head
|
||||
|
@ -256,10 +256,10 @@ class FundTransactionHandlingTest
|
||||
markAsReserved = true
|
||||
)
|
||||
|
||||
spendingInfos <- wallet.findOutputsBeingSpent(
|
||||
spendingInfos <- wallet.utxoHandling.findOutputsBeingSpent(
|
||||
fundRawTxHelper.unsignedTx
|
||||
)
|
||||
reserved <- wallet.listUtxos(TxoState.Reserved)
|
||||
reserved <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
} yield {
|
||||
assert(spendingInfos.exists(_.state == TxoState.Reserved))
|
||||
assert(reserved.size == spendingInfos.size)
|
||||
@ -277,10 +277,10 @@ class FundTransactionHandlingTest
|
||||
wallet.sendFundsHandling.sendToAddress(taggedAddr,
|
||||
destination.value * 2,
|
||||
Some(feeRate))
|
||||
taggedBalance <- wallet.getBalance(tag)
|
||||
taggedBalance <- wallet.utxoHandling.getBalance(tag)
|
||||
_ = assert(taggedBalance == destination.value * 2)
|
||||
|
||||
expectedUtxos <- wallet.listUtxos(tag)
|
||||
expectedUtxos <- wallet.utxoHandling.listUtxos(tag)
|
||||
fundRawTxHelper <-
|
||||
wallet.fundTxHandling
|
||||
.fundRawTransaction(
|
||||
|
@ -39,7 +39,7 @@ class ProcessBlockTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
val bitcoind = param.bitcoind
|
||||
|
||||
for {
|
||||
startingUtxos <- wallet.listUtxos()
|
||||
startingUtxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(startingUtxos.isEmpty)
|
||||
|
||||
addr <- wallet.getNewAddress()
|
||||
@ -51,11 +51,11 @@ class ProcessBlockTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
block <- bitcoind.getBlockRaw(hash)
|
||||
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
height <- bitcoind.getBlockCount()
|
||||
bestHash <- bitcoind.getBestBlockHash()
|
||||
syncHeightOpt <- wallet.getSyncDescriptorOpt()
|
||||
txDbOpt <- wallet.findByTxId(txId)
|
||||
txDbOpt <- wallet.transactionProcessing.findByTxId(txId)
|
||||
} yield {
|
||||
assert(syncHeightOpt.contains(SyncHeightDescriptor(bestHash, height)))
|
||||
assert(txDbOpt.isDefined)
|
||||
@ -71,7 +71,7 @@ class ProcessBlockTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
val wallet = param.wallet
|
||||
val bitcoind = param.bitcoind
|
||||
for {
|
||||
startingUtxos <- wallet.listUtxos(TxoState.ImmatureCoinbase)
|
||||
startingUtxos <- wallet.utxoHandling.listUtxos(TxoState.ImmatureCoinbase)
|
||||
startingBalance <- wallet.getBalance()
|
||||
_ = assert(startingUtxos.isEmpty)
|
||||
_ = assert(startingBalance == Satoshis.zero)
|
||||
@ -80,8 +80,9 @@ class ProcessBlockTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
blocks <- FutureUtil.sequentially(hashes)(bitcoind.getBlockRaw)
|
||||
_ <- FutureUtil.sequentially(blocks)(
|
||||
wallet.transactionProcessing.processBlock)
|
||||
coinbaseUtxos <- wallet.listUtxos(TxoState.ImmatureCoinbase)
|
||||
confirmedUtxos <- wallet.listUtxos(TxoState.ConfirmedReceived)
|
||||
coinbaseUtxos <- wallet.utxoHandling.listUtxos(TxoState.ImmatureCoinbase)
|
||||
confirmedUtxos <- wallet.utxoHandling.listUtxos(
|
||||
TxoState.ConfirmedReceived)
|
||||
balance <- wallet.getConfirmedBalance()
|
||||
|
||||
height <- bitcoind.getBlockCount()
|
||||
@ -104,7 +105,7 @@ class ProcessBlockTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
val bitcoind = param.bitcoind
|
||||
|
||||
for {
|
||||
startingUtxos <- wallet.listUtxos(TxoState.ImmatureCoinbase)
|
||||
startingUtxos <- wallet.utxoHandling.listUtxos(TxoState.ImmatureCoinbase)
|
||||
startingBalance <- wallet.getBalance()
|
||||
_ = assert(startingUtxos.isEmpty)
|
||||
_ = assert(startingBalance == Satoshis.zero)
|
||||
@ -115,8 +116,9 @@ class ProcessBlockTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
)
|
||||
filtersWithBlockHash = hashes.zip(filters.map(_.filter))
|
||||
_ <- wallet.processCompactFilters(filtersWithBlockHash)
|
||||
coinbaseUtxos <- wallet.listUtxos(TxoState.ImmatureCoinbase)
|
||||
confirmedUtxos <- wallet.listUtxos(TxoState.ConfirmedReceived)
|
||||
coinbaseUtxos <- wallet.utxoHandling.listUtxos(TxoState.ImmatureCoinbase)
|
||||
confirmedUtxos <- wallet.utxoHandling.listUtxos(
|
||||
TxoState.ConfirmedReceived)
|
||||
balance <- wallet.getConfirmedBalance()
|
||||
|
||||
height <- bitcoind.getBlockCount()
|
||||
|
@ -33,13 +33,13 @@ class ProcessTransactionTest extends BitcoinSWalletTest {
|
||||
wallet: WalletApi
|
||||
)(action: => Future[_]): Future[Assertion] =
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldUtxos <- wallet.listUtxos()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
oldUtxos <- wallet.utxoHandling.listUtxos()
|
||||
oldUnconfirmed <- wallet.getUnconfirmedBalance()
|
||||
oldConfirmed <- wallet.getBalance()
|
||||
_ <- action // by name
|
||||
newTransactions <- wallet.listTransactions()
|
||||
newUtxos <- wallet.listUtxos()
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
newUtxos <- wallet.utxoHandling.listUtxos()
|
||||
newUnconfirmed <- wallet.getUnconfirmedBalance()
|
||||
newConfirmed <- wallet.getBalance()
|
||||
|
||||
@ -79,7 +79,7 @@ class ProcessTransactionTest extends BitcoinSWalletTest {
|
||||
)
|
||||
newConfirmed <- wallet.getConfirmedBalance()
|
||||
newUnconfirmed <- wallet.getUnconfirmedBalance()
|
||||
utxosPostAdd <- wallet.listUtxos()
|
||||
utxosPostAdd <- wallet.utxoHandling.listUtxos()
|
||||
|
||||
// repeating the action should not make a difference
|
||||
_ <- checkUtxosAndBalance(wallet) {
|
||||
@ -118,7 +118,7 @@ class ProcessTransactionTest extends BitcoinSWalletTest {
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, None)
|
||||
newConfirmed <- wallet.getConfirmedBalance()
|
||||
newUnconfirmed <- wallet.getUnconfirmedBalance()
|
||||
utxosPostAdd <- wallet.listUtxos()
|
||||
utxosPostAdd <- wallet.utxoHandling.listUtxos()
|
||||
|
||||
// repeating the action should not make a difference
|
||||
_ <- checkUtxosAndBalance(wallet) {
|
||||
|
@ -49,7 +49,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
for {
|
||||
balance <- wallet.getBalance()
|
||||
_ = assert(balance != Satoshis.zero)
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(utxos.nonEmpty)
|
||||
|
||||
addresses <- wallet.addressHandling.listAddresses()
|
||||
@ -57,7 +57,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
|
||||
_ <- wallet.utxoHandling.clearAllUtxos()
|
||||
|
||||
clearedUtxos <- wallet.listUtxos()
|
||||
clearedUtxos <- wallet.utxoHandling.listUtxos()
|
||||
clearedAddresses <- wallet.addressHandling.listAddresses()
|
||||
} yield {
|
||||
assert(clearedUtxos.isEmpty)
|
||||
@ -194,7 +194,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
wallet.utxoHandling
|
||||
.listUtxos(account.hdAccount)
|
||||
.map(_.map(_.txid))
|
||||
_ <- wallet
|
||||
_ <- wallet.transactionProcessing
|
||||
.findByTxIds(txIds)
|
||||
.map(_.flatMap(_.blockHashOpt))
|
||||
|
||||
@ -274,10 +274,10 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
val initBalanceF = wallet.getBalance()
|
||||
|
||||
// find the first block a utxo was created in
|
||||
val utxosF = wallet.listUtxos()
|
||||
val utxosF = wallet.utxoHandling.listUtxos()
|
||||
val oldestHeightF = for {
|
||||
utxos <- utxosF
|
||||
blockhashes <- wallet
|
||||
blockhashes <- wallet.transactionProcessing
|
||||
.findByTxIds(utxos.map(_.txid))
|
||||
.map(_.flatMap(_.blockHashOpt))
|
||||
heights <- FutureUtil.sequentially(blockhashes) { hash =>
|
||||
@ -373,7 +373,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
block <- bitcoind.getBlockRaw(hashes.head)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
fundedAddresses <- wallet.addressHandling.listFundedAddresses()
|
||||
utxos <- wallet.listUtxos(TxoState.ImmatureCoinbase)
|
||||
utxos <- wallet.utxoHandling.listUtxos(TxoState.ImmatureCoinbase)
|
||||
} yield {
|
||||
// note 25 bitcoin reward from coinbase tx here
|
||||
// if we we move this test case in the future it may need to change
|
||||
@ -546,7 +546,7 @@ class RescanHandlingTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
wallet.utxoHandling
|
||||
.listUtxos(account.hdAccount)
|
||||
.map(_.map(_.txid))
|
||||
_ <- wallet
|
||||
_ <- wallet.transactionProcessing
|
||||
.findByTxIds(txIds)
|
||||
.map(_.flatMap(_.blockHashOpt))
|
||||
|
||||
|
@ -50,13 +50,13 @@ class UTXOLifeCycleTest
|
||||
val wallet = param.wallet
|
||||
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
tx <- wallet.sendFundsHandling.sendToAddress(testAddr,
|
||||
Satoshis(3000),
|
||||
None)
|
||||
|
||||
updatedCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
updatedCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
} yield {
|
||||
assert(updatedCoins.forall(_.state == TxoState.BroadcastSpent))
|
||||
assert(updatedCoins.forall(_.spendingTxIdOpt.contains(tx.txIdBE)))
|
||||
@ -70,13 +70,13 @@ class UTXOLifeCycleTest
|
||||
val bitcoind = param.bitcoind
|
||||
val walletConfig = param.walletConfig
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
tx <- wallet.sendFundsHandling.sendToAddress(testAddr,
|
||||
Satoshis(3000),
|
||||
None)
|
||||
|
||||
updatedCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
updatedCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
_ = assert(updatedCoins.forall(_.state == BroadcastSpent))
|
||||
_ = assert(!oldTransactions.map(_.transaction).contains(tx))
|
||||
_ = assert(newTransactions.map(_.transaction).contains(tx))
|
||||
@ -85,15 +85,15 @@ class UTXOLifeCycleTest
|
||||
hash <- bitcoind.getBestBlockHash()
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, Some(hash))
|
||||
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
pendingCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
pendingCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
_ = assert(pendingCoins.forall(_.state == PendingConfirmationsSpent))
|
||||
|
||||
// Put confirmations on top of the tx's block
|
||||
_ <- bitcoind.generate(walletConfig.requiredConfirmations)
|
||||
// Need to call this to actually update the state, normally a node callback would do this
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
confirmedCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
confirmedCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
} yield {
|
||||
assert(confirmedCoins.forall(_.state == ConfirmedSpent))
|
||||
assert(confirmedCoins.forall(_.spendingTxIdOpt.contains(tx.txIdBE)))
|
||||
@ -124,17 +124,17 @@ class UTXOLifeCycleTest
|
||||
addr2 <- wallet.getNewAddress()
|
||||
addr3 <- wallet.getNewAddress()
|
||||
|
||||
oldUtxos <- wallet.listUtxos()
|
||||
oldUtxos <- wallet.utxoHandling.listUtxos()
|
||||
|
||||
txid1 <- bitcoind.sendToAddress(addr1, Satoshis(1000))
|
||||
txid2 <- bitcoind.sendToAddress(addr2, Satoshis(2000))
|
||||
txid3 <- bitcoind.sendToAddress(addr3, Satoshis(3000))
|
||||
|
||||
tx1 <- wallet.findByTxId(txid1)
|
||||
tx1 <- wallet.transactionProcessing.findByTxId(txid1)
|
||||
_ = assert(tx1.isEmpty)
|
||||
tx2 <- wallet.findByTxId(txid2)
|
||||
tx2 <- wallet.transactionProcessing.findByTxId(txid2)
|
||||
_ = assert(tx2.isEmpty)
|
||||
tx3 <- wallet.findByTxId(txid3)
|
||||
tx3 <- wallet.transactionProcessing.findByTxId(txid3)
|
||||
_ = assert(tx3.isEmpty)
|
||||
|
||||
tx1 <- bitcoind.getRawTransactionRaw(txid1).map(Option.apply).recover {
|
||||
@ -150,7 +150,7 @@ class UTXOLifeCycleTest
|
||||
}
|
||||
_ = assert(tx3.nonEmpty)
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(oldUtxos == utxos)
|
||||
|
||||
// process the transactions from mempool
|
||||
@ -158,7 +158,7 @@ class UTXOLifeCycleTest
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx2.get, None)
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx3.get, None)
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(oldUtxos.size + 3 == utxos.size)
|
||||
|
||||
_ = checkState(utxos, txid1, txid2, txid3, TxoState.BroadcastReceived)
|
||||
@ -171,9 +171,9 @@ class UTXOLifeCycleTest
|
||||
blockHash = blockHashes.head
|
||||
block <- bitcoind.getBlockRaw(blockHash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(oldUtxos.size + 3 == utxos.size)
|
||||
|
||||
// mine the second block
|
||||
@ -182,9 +182,9 @@ class UTXOLifeCycleTest
|
||||
blockHash = blockHashes.head
|
||||
block <- bitcoind.getBlockRaw(blockHash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(oldUtxos.size + 3 == utxos.size)
|
||||
|
||||
_ = checkState(
|
||||
@ -201,9 +201,9 @@ class UTXOLifeCycleTest
|
||||
blockHash = blockHashes.head
|
||||
block <- bitcoind.getBlockRaw(blockHash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(oldUtxos.size + 3 == utxos.size)
|
||||
|
||||
_ = checkState(
|
||||
@ -220,9 +220,9 @@ class UTXOLifeCycleTest
|
||||
blockHash = blockHashes.head
|
||||
block <- bitcoind.getBlockRaw(blockHash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(oldUtxos.size + 3 == utxos.size)
|
||||
|
||||
_ = checkState(
|
||||
@ -239,9 +239,9 @@ class UTXOLifeCycleTest
|
||||
blockHash = blockHashes.head
|
||||
block <- bitcoind.getBlockRaw(blockHash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(oldUtxos.size + 3 == utxos.size)
|
||||
|
||||
_ = checkState(
|
||||
@ -258,9 +258,9 @@ class UTXOLifeCycleTest
|
||||
blockHash = blockHashes.head
|
||||
block <- bitcoind.getBlockRaw(blockHash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(oldUtxos.size + 3 == utxos.size)
|
||||
|
||||
utxo1 = utxos.find(_.txid == txid1).get
|
||||
@ -284,14 +284,14 @@ class UTXOLifeCycleTest
|
||||
Some(SatoshisPerByte.one)
|
||||
)
|
||||
|
||||
coins <- wallet.findOutputsBeingSpent(tx)
|
||||
coins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
_ = assert(coins.forall(_.state == BroadcastSpent))
|
||||
_ = assert(coins.forall(_.spendingTxIdOpt.contains(tx.txIdBE)))
|
||||
|
||||
rbf <- wallet.sendFundsHandling.bumpFeeRBF(tx.txIdBE,
|
||||
SatoshisPerByte.fromLong(3))
|
||||
_ <- wallet.transactionProcessing.processTransaction(rbf, None)
|
||||
rbfCoins <- wallet.findOutputsBeingSpent(rbf)
|
||||
rbfCoins <- wallet.utxoHandling.findOutputsBeingSpent(rbf)
|
||||
} yield {
|
||||
assert(rbfCoins.forall(_.state == BroadcastSpent))
|
||||
assert(rbfCoins.forall(_.spendingTxIdOpt.contains(rbf.txIdBE)))
|
||||
@ -308,7 +308,7 @@ class UTXOLifeCycleTest
|
||||
Satoshis(3000),
|
||||
None)
|
||||
|
||||
coins <- wallet.findOutputsBeingSpent(tx)
|
||||
coins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
|
||||
updatedCoins = coins.map(_.copyWithState(TxoState.ImmatureCoinbase))
|
||||
_ <- spendingInfoDAO.updateAllSpendingInfoDb(updatedCoins)
|
||||
@ -332,13 +332,13 @@ class UTXOLifeCycleTest
|
||||
val bitcoind = param.bitcoind
|
||||
val walletConfig = param.walletConfig
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
tx <- wallet.sendFundsHandling.sendToAddress(testAddr,
|
||||
Satoshis(3000),
|
||||
None)
|
||||
|
||||
updatedCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
updatedCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
_ = assert(updatedCoins.forall(_.state == BroadcastSpent))
|
||||
_ = assert(!oldTransactions.map(_.transaction).contains(tx))
|
||||
_ = assert(newTransactions.map(_.transaction).contains(tx))
|
||||
@ -347,15 +347,15 @@ class UTXOLifeCycleTest
|
||||
hash <- bitcoind.getBestBlockHash()
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, Some(hash))
|
||||
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
pendingCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
pendingCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
_ = assert(pendingCoins.forall(_.state == PendingConfirmationsSpent))
|
||||
|
||||
// Put confirmations on top of the tx's block
|
||||
_ <- bitcoind.generate(walletConfig.requiredConfirmations)
|
||||
// Need to call this to actually update the state, normally a node callback would do this
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
confirmedCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
confirmedCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
|
||||
// Assert tx is confirmed
|
||||
_ = assert(confirmedCoins.forall(_.state == ConfirmedSpent))
|
||||
@ -380,7 +380,7 @@ class UTXOLifeCycleTest
|
||||
val bitcoind = param.bitcoind
|
||||
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
addr <- wallet.getNewAddress()
|
||||
|
||||
txId <- bitcoind.sendToAddress(addr, Satoshis(3000))
|
||||
@ -395,8 +395,8 @@ class UTXOLifeCycleTest
|
||||
)
|
||||
|
||||
updatedCoin <-
|
||||
wallet.findByScriptPubKey(addr.scriptPubKey)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
wallet.utxoHandling.findByScriptPubKey(addr.scriptPubKey)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
} yield {
|
||||
assert(updatedCoin.forall(_.state == TxoState.BroadcastReceived))
|
||||
assert(!oldTransactions.map(_.transaction).contains(tx))
|
||||
@ -409,7 +409,7 @@ class UTXOLifeCycleTest
|
||||
val bitcoind = param.bitcoind
|
||||
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
addr <- wallet.getNewAddress()
|
||||
|
||||
txId <- bitcoind.sendToAddress(addr, Satoshis(3000))
|
||||
@ -424,8 +424,8 @@ class UTXOLifeCycleTest
|
||||
)
|
||||
|
||||
updatedCoin <-
|
||||
wallet.findByScriptPubKey(addr.scriptPubKey)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
wallet.utxoHandling.findByScriptPubKey(addr.scriptPubKey)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
_ = assert(updatedCoin.forall(_.state == TxoState.BroadcastReceived))
|
||||
|
||||
hash <- bitcoind.getNewAddress
|
||||
@ -434,7 +434,7 @@ class UTXOLifeCycleTest
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, Some(hash))
|
||||
|
||||
pendingCoins <-
|
||||
wallet.findByScriptPubKey(addr.scriptPubKey)
|
||||
wallet.utxoHandling.findByScriptPubKey(addr.scriptPubKey)
|
||||
} yield {
|
||||
assert(
|
||||
pendingCoins.forall(_.state == TxoState.PendingConfirmationsReceived)
|
||||
@ -449,7 +449,7 @@ class UTXOLifeCycleTest
|
||||
val bitcoind = param.bitcoind
|
||||
val walletConfig = param.walletConfig
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
addr <- wallet.getNewAddress()
|
||||
|
||||
blockHash <- bitcoind.getBestBlockHash()
|
||||
@ -466,8 +466,8 @@ class UTXOLifeCycleTest
|
||||
)
|
||||
|
||||
updatedCoin <-
|
||||
wallet.findByScriptPubKey(addr.scriptPubKey)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
wallet.utxoHandling.findByScriptPubKey(addr.scriptPubKey)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
_ = assert(updatedCoin.forall(_.state == PendingConfirmationsReceived))
|
||||
_ = assert(!oldTransactions.map(_.transaction).contains(tx))
|
||||
_ = assert(newTransactions.map(_.transaction).contains(tx))
|
||||
@ -475,9 +475,9 @@ class UTXOLifeCycleTest
|
||||
// Put confirmations on top of the tx's block
|
||||
_ <- bitcoind.generate(walletConfig.requiredConfirmations)
|
||||
// Need to call this to actually update the state, normally a node callback would do this
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
confirmedCoins <-
|
||||
wallet.findByScriptPubKey(addr.scriptPubKey)
|
||||
wallet.utxoHandling.findByScriptPubKey(addr.scriptPubKey)
|
||||
} yield assert(confirmedCoins.forall(_.state == ConfirmedReceived))
|
||||
}
|
||||
|
||||
@ -487,7 +487,7 @@ class UTXOLifeCycleTest
|
||||
val dummyOutput = TransactionOutput(Satoshis(3000), EmptyScriptPubKey)
|
||||
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
feeRate <- wallet.getFeeRate()
|
||||
rawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
|
||||
Vector(dummyOutput),
|
||||
@ -497,9 +497,9 @@ class UTXOLifeCycleTest
|
||||
)
|
||||
|
||||
tx = rawTxHelper.unsignedTx
|
||||
updatedCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
reserved <- wallet.listUtxos(TxoState.Reserved)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
updatedCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
reserved <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
} yield {
|
||||
assert(updatedCoins.forall(_.state == TxoState.Reserved))
|
||||
assert(updatedCoins.forall(reserved.contains))
|
||||
@ -516,7 +516,7 @@ class UTXOLifeCycleTest
|
||||
val dummyOutput = TransactionOutput(Satoshis(3000), EmptyScriptPubKey)
|
||||
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
feeRate <- wallet.getFeeRate()
|
||||
rawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
|
||||
Vector(dummyOutput),
|
||||
@ -526,14 +526,15 @@ class UTXOLifeCycleTest
|
||||
)
|
||||
|
||||
tx = rawTxHelper.unsignedTx
|
||||
reservedUtxos <- wallet.findOutputsBeingSpent(tx)
|
||||
allReserved <- wallet.listUtxos(TxoState.Reserved)
|
||||
reservedUtxos <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
allReserved <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
_ = assert(reservedUtxos.forall(_.state == TxoState.Reserved))
|
||||
_ = assert(reservedUtxos.forall(allReserved.contains))
|
||||
|
||||
unreservedUtxos <- wallet.unmarkUTXOsAsReserved(reservedUtxos)
|
||||
newReserved <- wallet.listUtxos(TxoState.Reserved)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
unreservedUtxos <- wallet.utxoHandling.unmarkUTXOsAsReserved(
|
||||
reservedUtxos)
|
||||
newReserved <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
} yield {
|
||||
assert(unreservedUtxos.forall(_.state != TxoState.Reserved))
|
||||
assert(newReserved.isEmpty)
|
||||
@ -549,7 +550,7 @@ class UTXOLifeCycleTest
|
||||
val dummyOutput = TransactionOutput(Satoshis(3000), EmptyScriptPubKey)
|
||||
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
feeRate <- wallet.getFeeRate()
|
||||
rawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
|
||||
Vector(dummyOutput),
|
||||
@ -559,15 +560,15 @@ class UTXOLifeCycleTest
|
||||
)
|
||||
|
||||
tx = rawTxHelper.unsignedTx
|
||||
allReserved <- wallet.listUtxos(TxoState.Reserved)
|
||||
allReserved <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
_ = assert(
|
||||
tx.inputs
|
||||
.map(_.previousOutput)
|
||||
.forall(allReserved.map(_.outPoint).contains)
|
||||
)
|
||||
|
||||
unreservedUtxos <- wallet.unmarkUTXOsAsReserved(tx)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
unreservedUtxos <- wallet.utxoHandling.unmarkUTXOsAsReserved(tx)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
} yield {
|
||||
assert(unreservedUtxos.forall(_.state != TxoState.Reserved))
|
||||
assert(!oldTransactions.map(_.transaction).contains(tx))
|
||||
@ -586,7 +587,7 @@ class UTXOLifeCycleTest
|
||||
)
|
||||
val accountF = wallet.accountHandling.getDefaultAccount()
|
||||
for {
|
||||
oldTransactions <- wallet.listTransactions()
|
||||
oldTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
account <- accountF
|
||||
rawTxHelper <- wallet.fundTxHandling.fundRawTransaction(
|
||||
destinations = Vector(dummyOutput),
|
||||
@ -599,7 +600,7 @@ class UTXOLifeCycleTest
|
||||
builderResult
|
||||
)
|
||||
tx = RawTxSigner.sign(unsignedTx, rawTxHelper.scriptSigParams)
|
||||
allReserved <- wallet.listUtxos(TxoState.Reserved)
|
||||
allReserved <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
_ = assert(
|
||||
tx.inputs
|
||||
.map(_.previousOutput)
|
||||
@ -615,8 +616,8 @@ class UTXOLifeCycleTest
|
||||
block <- bitcoind.getBlockRaw(hash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
|
||||
newReserved <- wallet.listUtxos(TxoState.Reserved)
|
||||
newTransactions <- wallet.listTransactions()
|
||||
newReserved <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
newTransactions <- wallet.transactionProcessing.listTransactions()
|
||||
} yield {
|
||||
assert(newReserved.isEmpty)
|
||||
assert(!oldTransactions.map(_.transaction).contains(tx))
|
||||
@ -630,7 +631,7 @@ class UTXOLifeCycleTest
|
||||
val bitcoind = param.bitcoind
|
||||
|
||||
for {
|
||||
utxo <- wallet.listUtxos().map(_.head)
|
||||
utxo <- wallet.utxoHandling.listUtxos().map(_.head)
|
||||
changeAddr <- wallet.getNewChangeAddress()
|
||||
unsignedPSBT = {
|
||||
val input =
|
||||
@ -667,7 +668,7 @@ class UTXOLifeCycleTest
|
||||
block <- bitcoind.getBlockRaw(hash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
|
||||
updatedCoins <- wallet.findOutputsBeingSpent(tx)
|
||||
updatedCoins <- wallet.utxoHandling.findOutputsBeingSpent(tx)
|
||||
} yield {
|
||||
assert(
|
||||
updatedCoins.forall(_.state == TxoState.PendingConfirmationsSpent)
|
||||
@ -679,13 +680,13 @@ class UTXOLifeCycleTest
|
||||
it must "fail to mark utxos as reserved if one of the utxos is already reserved" in {
|
||||
param =>
|
||||
val wallet = param.wallet
|
||||
val utxosF = wallet.listUtxos()
|
||||
val utxosF = wallet.utxoHandling.listUtxos()
|
||||
|
||||
val reservedUtxoF: Future[SpendingInfoDb] = for {
|
||||
utxos <- utxosF
|
||||
first = utxos.head
|
||||
// just reserve this one to start
|
||||
reserved <- wallet.markUTXOsAsReserved(Vector(first))
|
||||
reserved <- wallet.utxoHandling.markUTXOsAsReserved(Vector(first))
|
||||
} yield reserved.head
|
||||
|
||||
val reserveFailedF = for {
|
||||
@ -693,7 +694,7 @@ class UTXOLifeCycleTest
|
||||
_ <- reservedUtxoF
|
||||
// now try to reserve them all
|
||||
// this should fail as the first utxo is reserved
|
||||
_ <- wallet.markUTXOsAsReserved(utxos)
|
||||
_ <- wallet.utxoHandling.markUTXOsAsReserved(utxos)
|
||||
} yield ()
|
||||
|
||||
val assertionF = recoverToSucceededIf[RuntimeException](reserveFailedF)
|
||||
@ -701,7 +702,7 @@ class UTXOLifeCycleTest
|
||||
for {
|
||||
_ <- assertionF
|
||||
reserved <- reservedUtxoF
|
||||
utxos <- wallet.listUtxos(TxoState.Reserved)
|
||||
utxos <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
} yield {
|
||||
// make sure only 1 utxo is still reserved
|
||||
assert(utxos.length == 1)
|
||||
@ -726,15 +727,16 @@ class UTXOLifeCycleTest
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
|
||||
// make sure the utxo is pending confirmations received
|
||||
utxos <- wallet.listUtxos(TxoState.PendingConfirmationsReceived)
|
||||
utxos <- wallet.utxoHandling.listUtxos(
|
||||
TxoState.PendingConfirmationsReceived)
|
||||
_ = assert(utxos.length == 1)
|
||||
utxo = utxos.head
|
||||
_ = assert(utxo.txid == txId)
|
||||
_ = assert(utxo.state == TxoState.PendingConfirmationsReceived)
|
||||
// now mark the utxo as reserved
|
||||
_ <- wallet.markUTXOsAsReserved(Vector(utxo))
|
||||
_ <- wallet.utxoHandling.markUTXOsAsReserved(Vector(utxo))
|
||||
// confirm it is reserved
|
||||
_ <- wallet
|
||||
_ <- wallet.utxoHandling
|
||||
.listUtxos(TxoState.Reserved)
|
||||
.map(utxos =>
|
||||
assert(utxos.contains(utxo.copyWithState(TxoState.Reserved))))
|
||||
@ -745,7 +747,7 @@ class UTXOLifeCycleTest
|
||||
_ <- wallet.transactionProcessing.processBlock(block2)
|
||||
|
||||
// the utxo should still be reserved
|
||||
reservedUtxos <- wallet.listUtxos(TxoState.Reserved)
|
||||
reservedUtxos <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
reservedUtxo = reservedUtxos.head
|
||||
} yield {
|
||||
assert(reservedUtxo.txid == txId)
|
||||
@ -759,7 +761,7 @@ class UTXOLifeCycleTest
|
||||
val bitcoind = param.bitcoind
|
||||
val bitcoindAddrF = bitcoind.getNewAddress
|
||||
val amt = Satoshis(100000)
|
||||
val utxoCountF = wallet.listUtxos()
|
||||
val utxoCountF = wallet.utxoHandling.listUtxos()
|
||||
for {
|
||||
bitcoindAdr <- bitcoindAddrF
|
||||
utxoCount <- utxoCountF
|
||||
@ -767,33 +769,34 @@ class UTXOLifeCycleTest
|
||||
tx <- wallet.sendFundsHandling.sendToAddress(bitcoindAdr,
|
||||
amt,
|
||||
SatoshisPerVirtualByte.one)
|
||||
c <- wallet.listUtxos()
|
||||
c <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(c.length == utxoCount.length)
|
||||
txIdBE <- bitcoind.sendRawTransaction(tx)
|
||||
|
||||
// find all utxos that we can use to fund a transaction
|
||||
utxos <- wallet
|
||||
utxos <- wallet.utxoHandling
|
||||
.listUtxos()
|
||||
.map(_.filter(u => TxoState.receivedStates.contains(u.state)))
|
||||
broadcastReceived <- wallet.listUtxos(TxoState.BroadcastReceived)
|
||||
broadcastReceived <- wallet.utxoHandling.listUtxos(
|
||||
TxoState.BroadcastReceived)
|
||||
_ = assert(broadcastReceived.length == 1) // change output
|
||||
|
||||
// mark all utxos as reserved
|
||||
_ <- wallet.markUTXOsAsReserved(utxos)
|
||||
newReservedUtxos <- wallet.listUtxos(TxoState.Reserved)
|
||||
_ <- wallet.utxoHandling.markUTXOsAsReserved(utxos)
|
||||
newReservedUtxos <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
|
||||
// make sure all utxos are reserved
|
||||
_ = assert(newReservedUtxos.length == utxoCount.length)
|
||||
blockHash <- bitcoind.generateToAddress(1, bitcoindAdr).map(_.head)
|
||||
block <- bitcoind.getBlockRaw(blockHash)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
broadcastSpentUtxo <- wallet.listUtxos(
|
||||
broadcastSpentUtxo <- wallet.utxoHandling.listUtxos(
|
||||
TxoState.PendingConfirmationsSpent
|
||||
)
|
||||
pendingConfirmationsReceivedUtxos <- wallet.listUtxos(
|
||||
pendingConfirmationsReceivedUtxos <- wallet.utxoHandling.listUtxos(
|
||||
TxoState.PendingConfirmationsReceived
|
||||
)
|
||||
finalReservedUtxos <- wallet.listUtxos(TxoState.Reserved)
|
||||
finalReservedUtxos <- wallet.utxoHandling.listUtxos(TxoState.Reserved)
|
||||
} yield {
|
||||
assert(newReservedUtxos == finalReservedUtxos)
|
||||
assert(pendingConfirmationsReceivedUtxos.isEmpty)
|
||||
@ -829,7 +832,8 @@ class UTXOLifeCycleTest
|
||||
UInt32(receiveOutPointPair._2)
|
||||
)
|
||||
|
||||
receivedUtxo <- wallet.findByOutPoints(Vector(receiveOutPoint))
|
||||
receivedUtxo <- wallet.utxoHandling.findByOutPoints(
|
||||
Vector(receiveOutPoint))
|
||||
_ = assert(receivedUtxo.size == 1)
|
||||
_ = assert(receivedUtxo.head.state == BroadcastReceived)
|
||||
|
||||
@ -843,7 +847,8 @@ class UTXOLifeCycleTest
|
||||
)
|
||||
_ <- wallet.broadcastTransaction(sendTx)
|
||||
|
||||
receivedUtxo <- wallet.findByOutPoints(Vector(receiveOutPoint))
|
||||
receivedUtxo <- wallet.utxoHandling.findByOutPoints(
|
||||
Vector(receiveOutPoint))
|
||||
_ = assert(receivedUtxo.size == 1)
|
||||
_ = assert(receivedUtxo.head.state == BroadcastSpent)
|
||||
|
||||
@ -852,7 +857,8 @@ class UTXOLifeCycleTest
|
||||
block <- bitcoind.getBlockRaw(blockHashes.head)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
|
||||
receivedUtxo <- wallet.findByOutPoints(Vector(receiveOutPoint))
|
||||
receivedUtxo <- wallet.utxoHandling.findByOutPoints(
|
||||
Vector(receiveOutPoint))
|
||||
} yield {
|
||||
assert(receivedUtxo.size == 1)
|
||||
assert(receivedUtxo.head.state == PendingConfirmationsSpent)
|
||||
@ -883,7 +889,8 @@ class UTXOLifeCycleTest
|
||||
UInt32(receiveOutPointPair._2)
|
||||
)
|
||||
|
||||
receivedUtxo <- wallet.findByOutPoints(Vector(receiveOutPoint))
|
||||
receivedUtxo <- wallet.utxoHandling.findByOutPoints(
|
||||
Vector(receiveOutPoint))
|
||||
_ = assert(receivedUtxo.size == 1)
|
||||
_ = assert(receivedUtxo.head.state == BroadcastReceived)
|
||||
|
||||
@ -896,7 +903,8 @@ class UTXOLifeCycleTest
|
||||
CoinSelectionAlgo.SelectedUtxos(Set(receiveOutPointPair))
|
||||
)
|
||||
|
||||
receivedUtxo <- wallet.findByOutPoints(Vector(receiveOutPoint))
|
||||
receivedUtxo <- wallet.utxoHandling.findByOutPoints(
|
||||
Vector(receiveOutPoint))
|
||||
_ = assert(receivedUtxo.size == 1)
|
||||
_ = assert(receivedUtxo.head.state == BroadcastSpent)
|
||||
|
||||
@ -905,7 +913,8 @@ class UTXOLifeCycleTest
|
||||
block <- bitcoind.getBlockRaw(blockHashes.head)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
|
||||
receivedUtxo <- wallet.findByOutPoints(Vector(receiveOutPoint))
|
||||
receivedUtxo <- wallet.utxoHandling.findByOutPoints(
|
||||
Vector(receiveOutPoint))
|
||||
_ = assert(receivedUtxo.size == 1)
|
||||
_ = assert(receivedUtxo.head.state == BroadcastSpent)
|
||||
|
||||
@ -915,7 +924,8 @@ class UTXOLifeCycleTest
|
||||
block <- bitcoind.getBlockRaw(blockHashes.head)
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
|
||||
receivedUtxo <- wallet.findByOutPoints(Vector(receiveOutPoint))
|
||||
receivedUtxo <- wallet.utxoHandling.findByOutPoints(
|
||||
Vector(receiveOutPoint))
|
||||
} yield {
|
||||
assert(receivedUtxo.size == 1)
|
||||
assert(receivedUtxo.head.state == PendingConfirmationsSpent)
|
||||
|
@ -109,10 +109,10 @@ class WalletCallbackTest extends BitcoinSWalletTest {
|
||||
)
|
||||
|
||||
for {
|
||||
txno <- wallet.listTransactions().map(_.size)
|
||||
txno <- wallet.transactionProcessing.listTransactions().map(_.size)
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, None)
|
||||
_ <- AsyncUtil.nonBlockingSleep(50.millis)
|
||||
txs <- wallet.listTransactions()
|
||||
txs <- wallet.transactionProcessing.listTransactions()
|
||||
} yield {
|
||||
assert(txs.size == txno)
|
||||
assert(!resultP.isCompleted)
|
||||
@ -160,8 +160,8 @@ class WalletCallbackTest extends BitcoinSWalletTest {
|
||||
val wallet = fundedWallet.wallet
|
||||
|
||||
for {
|
||||
utxos <- wallet.listUtxos()
|
||||
_ <- wallet.markUTXOsAsReserved(Vector(utxos.head))
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ <- wallet.utxoHandling.markUTXOsAsReserved(Vector(utxos.head))
|
||||
result <- resultP.future
|
||||
} yield assert(
|
||||
// just compare outPoints because states will be changed so they won't be equal
|
||||
@ -185,11 +185,11 @@ class WalletCallbackTest extends BitcoinSWalletTest {
|
||||
val wallet = fundedWallet.wallet
|
||||
|
||||
for {
|
||||
utxos <- wallet.listUtxos()
|
||||
reserved <- wallet.markUTXOsAsReserved(Vector(utxos.head))
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
reserved <- wallet.utxoHandling.markUTXOsAsReserved(Vector(utxos.head))
|
||||
_ = fundedWallet.wallet.walletConfig.addCallbacks(callbacks)
|
||||
|
||||
_ <- wallet.unmarkUTXOsAsReserved(reserved)
|
||||
_ <- wallet.utxoHandling.unmarkUTXOsAsReserved(reserved)
|
||||
result <- resultP.future
|
||||
// just compare outPoints because states will be changed so they won't be equal
|
||||
} yield assert(result.map(_.outPoint) == reserved.map(_.outPoint))
|
||||
|
@ -62,7 +62,7 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
tx <- bitcoind.getRawTransactionRaw(txId)
|
||||
|
||||
// before processing TX, wallet should be completely empty
|
||||
_ <- wallet.listUtxos().map(utxos => assert(utxos.isEmpty))
|
||||
_ <- wallet.utxoHandling.listUtxos().map(utxos => assert(utxos.isEmpty))
|
||||
_ <- wallet.getBalance().map(confirmed => assert(confirmed == 0.bitcoin))
|
||||
_ <-
|
||||
wallet
|
||||
@ -74,7 +74,7 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
|
||||
// we should now have one UTXO in the wallet
|
||||
// it should not be confirmed
|
||||
utxosPostAdd <- wallet.listUtxos()
|
||||
utxosPostAdd <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(utxosPostAdd.length == 1)
|
||||
_ <-
|
||||
wallet
|
||||
@ -94,7 +94,7 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
// after this, tx should be confirmed
|
||||
_ <- wallet.transactionProcessing.processTransaction(tx, rawTx.blockhash)
|
||||
_ <-
|
||||
wallet
|
||||
wallet.utxoHandling
|
||||
.listUtxos()
|
||||
.map { utxos =>
|
||||
// we want to make sure no new utxos were added,
|
||||
@ -126,7 +126,7 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
_ <- bitcoind.generate(1)
|
||||
tx <- bitcoind.getRawTransaction(txid)
|
||||
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = utxos match {
|
||||
case utxo +: Vector() =>
|
||||
assert(utxo.privKeyPath.chain.chainType == HDChainType.Change)
|
||||
@ -225,7 +225,7 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
|
||||
replacementInfo <- bitcoind.getRawTransaction(replacementTx.txIdBE)
|
||||
|
||||
utxos <- wallet.findOutputsBeingSpent(replacementTx)
|
||||
utxos <- wallet.utxoHandling.findOutputsBeingSpent(replacementTx)
|
||||
} yield {
|
||||
assert(utxos.forall(_.spendingTxIdOpt.contains(replacementTx.txIdBE)))
|
||||
// Check correct one was confirmed
|
||||
@ -339,9 +339,9 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
_ <- wallet.transactionProcessing.processBlock(block)
|
||||
|
||||
// Verify we funded the wallet
|
||||
allUtxos <- wallet.listUtxos()
|
||||
allUtxos <- wallet.utxoHandling.listUtxos()
|
||||
_ = assert(allUtxos.size == 1)
|
||||
utxos <- wallet.listUtxos(TxoState.ImmatureCoinbase)
|
||||
utxos <- wallet.utxoHandling.listUtxos(TxoState.ImmatureCoinbase)
|
||||
_ = assert(utxos.size == 1)
|
||||
|
||||
bitcoindAddr <- bitcoind.getNewAddress
|
||||
@ -368,7 +368,7 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
|
||||
// Make coinbase mature
|
||||
_ <- bitcoind.generateToAddress(101, bitcoindAddr)
|
||||
_ <- wallet.updateUtxoPendingStates()
|
||||
_ <- wallet.utxoHandling.updateUtxoPendingStates()
|
||||
|
||||
// Create valid spending tx
|
||||
psbt = PSBT.fromUnsignedTx(spendingTx)
|
||||
@ -379,9 +379,10 @@ class WalletIntegrationTest extends BitcoinSWalletTestCachedBitcoindNewest {
|
||||
|
||||
// Process tx, validate correctly moved to
|
||||
_ <- wallet.transactionProcessing.processTransaction(signedTx, None)
|
||||
newCoinbaseUtxos <- wallet.listUtxos(TxoState.ImmatureCoinbase)
|
||||
newCoinbaseUtxos <- wallet.utxoHandling.listUtxos(
|
||||
TxoState.ImmatureCoinbase)
|
||||
_ = assert(newCoinbaseUtxos.isEmpty)
|
||||
spentUtxos <- wallet.listUtxos(TxoState.BroadcastSpent)
|
||||
spentUtxos <- wallet.utxoHandling.listUtxos(TxoState.BroadcastSpent)
|
||||
_ = assert(spentUtxos.size == 1)
|
||||
|
||||
// Assert spending tx valid to bitcoind
|
||||
|
@ -238,7 +238,7 @@ class WalletSendingTest extends BitcoinSWalletTest {
|
||||
it should "correctly send entire outpoints" in { fundedWallet =>
|
||||
val wallet = fundedWallet.wallet
|
||||
for {
|
||||
allUtxos <- wallet.listUtxos()
|
||||
allUtxos <- wallet.utxoHandling.listUtxos()
|
||||
// use half of them
|
||||
utxos = allUtxos.drop(allUtxos.size / 2)
|
||||
outPoints = utxos.map(_.outPoint)
|
||||
@ -287,7 +287,7 @@ class WalletSendingTest extends BitcoinSWalletTest {
|
||||
it should "correctly sweep the wallet" in { fundedWallet =>
|
||||
val wallet = fundedWallet.wallet
|
||||
for {
|
||||
utxos <- wallet.listUtxos()
|
||||
utxos <- wallet.utxoHandling.listUtxos()
|
||||
tx <- wallet.sendFundsHandling.sweepWallet(testAddress, None)
|
||||
balance <- wallet.getBalance()
|
||||
} yield {
|
||||
@ -387,7 +387,7 @@ class WalletSendingTest extends BitcoinSWalletTest {
|
||||
|
||||
for {
|
||||
addr <- wallet.getNewAddress()
|
||||
utxo <- wallet.listUtxos().map(_.head)
|
||||
utxo <- wallet.utxoHandling.listUtxos().map(_.head)
|
||||
|
||||
// Create tx not signaling RBF
|
||||
input = TransactionInput(
|
||||
@ -485,7 +485,7 @@ class WalletSendingTest extends BitcoinSWalletTest {
|
||||
fundedWallet =>
|
||||
val wallet = fundedWallet.wallet
|
||||
for {
|
||||
allUtxos <- wallet.listUtxos()
|
||||
allUtxos <- wallet.utxoHandling.listUtxos()
|
||||
// Make one already spent
|
||||
spent = allUtxos.head
|
||||
.copyWithSpendingTxId(
|
||||
|
@ -346,7 +346,7 @@ class WalletUnitTest extends BitcoinSWalletTest {
|
||||
_ <- wallet.transactionProcessing.processTransaction(dummyPrevTx1,
|
||||
blockHashOpt = None)
|
||||
|
||||
toBroadcast <- wallet.getTransactionsToBroadcast
|
||||
toBroadcast <- wallet.sendFundsHandling.getTransactionsToBroadcast
|
||||
} yield assert(toBroadcast.map(_.txIdBE) == Vector(dummyPrevTx1.txIdBE))
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,7 @@ import org.apache.pekko.actor.ActorSystem
|
||||
import org.bitcoins.core.api.chain.ChainQueryApi
|
||||
import org.bitcoins.core.api.feeprovider.FeeRateApi
|
||||
import org.bitcoins.core.api.node.NodeApi
|
||||
import org.bitcoins.core.api.wallet.db.{
|
||||
AccountDb,
|
||||
SpendingInfoDb,
|
||||
TransactionDb
|
||||
}
|
||||
import org.bitcoins.core.api.wallet.db.AccountDb
|
||||
import org.bitcoins.core.api.wallet.*
|
||||
import org.bitcoins.core.config.BitcoinNetwork
|
||||
import org.bitcoins.core.crypto.ExtPublicKey
|
||||
@ -21,8 +17,6 @@ import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.transaction.*
|
||||
import org.bitcoins.core.util.{FutureUtil, HDUtil}
|
||||
import org.bitcoins.core.wallet.fee.*
|
||||
import org.bitcoins.core.wallet.utxo.*
|
||||
import org.bitcoins.core.wallet.utxo.TxoState.*
|
||||
import org.bitcoins.crypto.*
|
||||
import org.bitcoins.db.SafeDatabase
|
||||
import org.bitcoins.db.models.MasterXPubDAO
|
||||
@ -284,16 +278,6 @@ abstract class Wallet extends NeutrinoHDWalletApi with WalletLogger {
|
||||
_ <- walletCallbacks.executeOnTransactionBroadcast(transaction)
|
||||
} yield ()
|
||||
|
||||
override def getTransactionsToBroadcast: Future[Vector[Transaction]] = {
|
||||
for {
|
||||
mempoolUtxos <- spendingInfoDAO.findAllInMempool
|
||||
txIds = mempoolUtxos.map { utxo =>
|
||||
utxo.spendingTxIdOpt.getOrElse(utxo.txid)
|
||||
}
|
||||
txDbs <- transactionDAO.findByTxIdBEs(txIds)
|
||||
} yield txDbs.map(_.transaction)
|
||||
}
|
||||
|
||||
override def isEmpty(): Future[Boolean] =
|
||||
for {
|
||||
addressCount <- addressDAO.count()
|
||||
@ -309,51 +293,11 @@ abstract class Wallet extends NeutrinoHDWalletApi with WalletLogger {
|
||||
override def getConfirmedBalance(): Future[CurrencyUnit] = {
|
||||
safeDatabase.run(spendingInfoDAO.getConfirmedBalanceAction())
|
||||
}
|
||||
override def getConfirmedBalance(tag: AddressTag): Future[CurrencyUnit] = {
|
||||
spendingInfoDAO.findAllUnspentForTag(tag).map { allUnspent =>
|
||||
val confirmed = allUnspent.filter(_.state == ConfirmedReceived)
|
||||
confirmed.foldLeft(CurrencyUnits.zero)(_ + _.output.value)
|
||||
}
|
||||
}
|
||||
|
||||
override def getUnconfirmedBalance(): Future[CurrencyUnit] = {
|
||||
safeDatabase.run(spendingInfoDAO.getUnconfirmedBalanceAction())
|
||||
}
|
||||
|
||||
override def getUnconfirmedBalance(tag: AddressTag): Future[CurrencyUnit] = {
|
||||
spendingInfoDAO.findAllUnspentForTag(tag).map { allUnspent =>
|
||||
val confirmed = allUnspent
|
||||
.filter(utxo => TxoState.pendingReceivedStates.contains(utxo.state))
|
||||
confirmed.foldLeft(CurrencyUnits.zero)(_ + _.output.value)
|
||||
}
|
||||
}
|
||||
|
||||
override def findByOutPoints(
|
||||
outPoints: Vector[TransactionOutPoint]
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
spendingInfoDAO.findByOutPoints(outPoints)
|
||||
}
|
||||
|
||||
override def findByTxIds(
|
||||
txIds: Vector[DoubleSha256DigestBE]
|
||||
): Future[Vector[TransactionDb]] = {
|
||||
transactionDAO.findByTxIds(txIds)
|
||||
}
|
||||
|
||||
override def findOutputsBeingSpent(
|
||||
tx: Transaction
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
spendingInfoDAO.findOutputsBeingSpent(tx)
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
override def isChange(output: TransactionOutput): Future[Boolean] = {
|
||||
addressDAO.findByScriptPubKey(output.scriptPubKey).map {
|
||||
case Some(db) => db.isChange
|
||||
case None => false
|
||||
}
|
||||
}
|
||||
|
||||
override def getWalletName(): Future[String] = {
|
||||
Future.successful(walletConfig.walletName)
|
||||
}
|
||||
@ -377,12 +321,6 @@ abstract class Wallet extends NeutrinoHDWalletApi with WalletLogger {
|
||||
}
|
||||
}
|
||||
|
||||
override def findByScriptPubKey(
|
||||
scriptPubKey: ScriptPubKey
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
spendingInfoDAO.findByScriptPubKey(scriptPubKey)
|
||||
}
|
||||
|
||||
def startFeeRateCallbackScheduler(): Unit = {
|
||||
val feeRateChangedRunnable = new Runnable {
|
||||
override def run(): Unit = {
|
||||
@ -408,46 +346,6 @@ abstract class Wallet extends NeutrinoHDWalletApi with WalletLogger {
|
||||
TimeUnit.SECONDS
|
||||
)
|
||||
}
|
||||
|
||||
override def updateUtxoPendingStates(): Future[Vector[SpendingInfoDb]] =
|
||||
utxoHandling.updateUtxoPendingStates()
|
||||
|
||||
override def listTransactions(): Future[Vector[TransactionDb]] =
|
||||
transactionProcessing.listTransactions()
|
||||
|
||||
override def listUtxos(): Future[Vector[SpendingInfoDb]] =
|
||||
utxoHandling.listUtxos()
|
||||
|
||||
override def listUtxos(state: TxoState): Future[Vector[SpendingInfoDb]] =
|
||||
utxoHandling.listUtxos(state)
|
||||
|
||||
override def listUtxos(tag: AddressTag): Future[Vector[SpendingInfoDb]] = {
|
||||
utxoHandling.listUtxos(tag)
|
||||
}
|
||||
|
||||
def markUTXOsAsReserved(
|
||||
utxos: Vector[SpendingInfoDb]): Future[Vector[SpendingInfoDb]] = {
|
||||
utxoHandling.markUTXOsAsReserved(utxos)
|
||||
}
|
||||
|
||||
/** Marks all utxos that are ours in this transactions as reserved */
|
||||
override def markUTXOsAsReserved(
|
||||
tx: Transaction): Future[Vector[SpendingInfoDb]] = {
|
||||
utxoHandling.markUTXOsAsReserved(tx)
|
||||
}
|
||||
|
||||
override def unmarkUTXOsAsReserved(
|
||||
utxos: Vector[SpendingInfoDb]): Future[Vector[SpendingInfoDb]] = {
|
||||
utxoHandling.unmarkUTXOsAsReserved(utxos)
|
||||
}
|
||||
|
||||
/** Unmarks all utxos that are ours in this transactions indicating they are
|
||||
* no longer reserved
|
||||
*/
|
||||
override def unmarkUTXOsAsReserved(
|
||||
tx: Transaction): Future[Vector[SpendingInfoDb]] = {
|
||||
utxoHandling.unmarkUTXOsAsReserved(tx)
|
||||
}
|
||||
}
|
||||
|
||||
// todo: create multiple wallets, need to maintain multiple databases
|
||||
|
@ -11,23 +11,16 @@ import org.bitcoins.core.api.dlc.wallet.db.{
|
||||
import org.bitcoins.core.api.feeprovider.FeeRateApi
|
||||
import org.bitcoins.core.api.node.NodeApi
|
||||
import org.bitcoins.core.api.wallet.*
|
||||
import org.bitcoins.core.api.wallet.db.*
|
||||
import org.bitcoins.core.currency.{CurrencyUnit, Satoshis}
|
||||
import org.bitcoins.core.dlc.accounting.DLCWalletAccounting
|
||||
import org.bitcoins.core.gcs.GolombFilter
|
||||
import org.bitcoins.core.hd.HDAccount
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.dlc.models.*
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.tlv.*
|
||||
import org.bitcoins.core.protocol.transaction.{
|
||||
Transaction,
|
||||
TransactionOutPoint,
|
||||
TransactionOutput
|
||||
}
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerVirtualByte}
|
||||
import org.bitcoins.core.wallet.utxo.{AddressTag, TxoState}
|
||||
import org.bitcoins.crypto.{DoubleSha256DigestBE, Sha256Digest}
|
||||
import scodec.bits.ByteVector
|
||||
|
||||
@ -136,60 +129,16 @@ class WalletHolder(initWalletOpt: Option[DLCNeutrinoHDWalletApi])(implicit
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
override def updateUtxoPendingStates(): Future[Vector[SpendingInfoDb]] =
|
||||
delegate(_.updateUtxoPendingStates())
|
||||
|
||||
override def getConfirmedBalance(): Future[CurrencyUnit] = delegate(
|
||||
_.getConfirmedBalance()
|
||||
)
|
||||
|
||||
override def getConfirmedBalance(tag: AddressTag): Future[CurrencyUnit] =
|
||||
delegate(_.getConfirmedBalance(tag))
|
||||
|
||||
override def getUnconfirmedBalance(): Future[CurrencyUnit] = delegate(
|
||||
_.getUnconfirmedBalance()
|
||||
)
|
||||
|
||||
override def getUnconfirmedBalance(tag: AddressTag): Future[CurrencyUnit] =
|
||||
delegate(_.getUnconfirmedBalance(tag))
|
||||
|
||||
override def listTransactions(): Future[Vector[TransactionDb]] = {
|
||||
delegate(_.listTransactions())
|
||||
}
|
||||
override def listUtxos(): Future[Vector[SpendingInfoDb]] = delegate(
|
||||
_.listUtxos()
|
||||
)
|
||||
|
||||
override def listUtxos(state: TxoState): Future[Vector[SpendingInfoDb]] =
|
||||
delegate(_.listUtxos(state))
|
||||
|
||||
override def listUtxos(tag: AddressTag): Future[Vector[SpendingInfoDb]] = {
|
||||
delegate(_.listUtxos(tag))
|
||||
}
|
||||
|
||||
override def markUTXOsAsReserved(
|
||||
utxos: Vector[SpendingInfoDb]
|
||||
): Future[Vector[SpendingInfoDb]] = delegate(_.markUTXOsAsReserved(utxos))
|
||||
|
||||
override def markUTXOsAsReserved(
|
||||
tx: Transaction
|
||||
): Future[Vector[SpendingInfoDb]] = delegate(_.markUTXOsAsReserved(tx))
|
||||
|
||||
override def unmarkUTXOsAsReserved(
|
||||
utxos: Vector[SpendingInfoDb]
|
||||
): Future[Vector[SpendingInfoDb]] = delegate(_.unmarkUTXOsAsReserved(utxos))
|
||||
|
||||
override def unmarkUTXOsAsReserved(
|
||||
tx: Transaction
|
||||
): Future[Vector[SpendingInfoDb]] = delegate(_.unmarkUTXOsAsReserved(tx))
|
||||
|
||||
override def isEmpty(): Future[Boolean] = delegate(_.isEmpty())
|
||||
|
||||
override def isChange(output: TransactionOutput): Future[Boolean] = delegate(
|
||||
_.isChange(output)
|
||||
)
|
||||
|
||||
override def getSyncState(): Future[BlockSyncState] = delegate(
|
||||
_.getSyncState()
|
||||
)
|
||||
@ -375,20 +324,12 @@ class WalletHolder(initWalletOpt: Option[DLCNeutrinoHDWalletApi])(implicit
|
||||
override def broadcastTransaction(transaction: Transaction): Future[Unit] =
|
||||
delegate(_.broadcastTransaction(transaction))
|
||||
|
||||
override def getTransactionsToBroadcast: Future[Vector[Transaction]] = {
|
||||
delegate(_.getTransactionsToBroadcast)
|
||||
}
|
||||
|
||||
override def getFeeRate(): Future[FeeUnit] = delegate(_.getFeeRate())
|
||||
|
||||
override def getBalance()(implicit
|
||||
ec: ExecutionContext
|
||||
): Future[CurrencyUnit] = delegate(_.getBalance())
|
||||
|
||||
override def getBalance(tag: AddressTag)(implicit
|
||||
ec: ExecutionContext
|
||||
): Future[CurrencyUnit] = delegate(_.getBalance(tag))
|
||||
|
||||
def getBalance(account: HDAccount)(implicit
|
||||
ec: ExecutionContext
|
||||
): Future[CurrencyUnit] = delegate(_.accountHandling.getBalance(account))
|
||||
@ -466,30 +407,6 @@ class WalletHolder(initWalletOpt: Option[DLCNeutrinoHDWalletApi])(implicit
|
||||
oracleSig: OracleSignatures
|
||||
): Future[Option[Transaction]] =
|
||||
delegate(_.executeDLC(contractId, oracleSig))
|
||||
|
||||
override def findByOutPoints(
|
||||
outPoints: Vector[TransactionOutPoint]
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
delegate(_.findByOutPoints(outPoints))
|
||||
}
|
||||
|
||||
override def findByTxIds(
|
||||
txIds: Vector[DoubleSha256DigestBE]
|
||||
): Future[Vector[TransactionDb]] = {
|
||||
delegate(_.findByTxIds(txIds))
|
||||
}
|
||||
|
||||
override def findOutputsBeingSpent(
|
||||
tx: Transaction
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
delegate(_.findOutputsBeingSpent(tx))
|
||||
}
|
||||
|
||||
override def findByScriptPubKey(
|
||||
scriptPubKey: ScriptPubKey
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
delegate(_.findByScriptPubKey(scriptPubKey))
|
||||
}
|
||||
}
|
||||
|
||||
object WalletHolder {
|
||||
|
@ -439,7 +439,7 @@ object WalletAppConfig
|
||||
|
||||
override def run(): Unit = {
|
||||
val f = for {
|
||||
txs <- wallet.getTransactionsToBroadcast
|
||||
txs <- wallet.sendFundsHandling.getTransactionsToBroadcast
|
||||
|
||||
_ = {
|
||||
if (txs.size > 1)
|
||||
|
@ -293,6 +293,13 @@ case class AddressHandling(
|
||||
}
|
||||
}
|
||||
|
||||
override def isChange(output: TransactionOutput): Future[Boolean] = {
|
||||
addressDAO.findByScriptPubKey(output.scriptPubKey).map {
|
||||
case Some(db) => db.isChange
|
||||
case None => false
|
||||
}
|
||||
}
|
||||
|
||||
override def tagAddress(
|
||||
address: BitcoinAddress,
|
||||
tag: AddressTag
|
||||
|
@ -230,6 +230,16 @@ case class SendFundsHandlingHandling(
|
||||
} yield childTx
|
||||
}
|
||||
|
||||
override def getTransactionsToBroadcast: Future[Vector[Transaction]] = {
|
||||
for {
|
||||
mempoolUtxos <- spendingInfoDAO.findAllInMempool
|
||||
txIds = mempoolUtxos.map { utxo =>
|
||||
utxo.spendingTxIdOpt.getOrElse(utxo.txid)
|
||||
}
|
||||
txDbs <- transactionDAO.findByTxIdBEs(txIds)
|
||||
} yield txDbs.map(_.transaction)
|
||||
}
|
||||
|
||||
override def makeOpReturnCommitment(
|
||||
message: String,
|
||||
hashMessage: Boolean,
|
||||
|
@ -73,6 +73,11 @@ case class TransactionProcessing(
|
||||
|
||||
/////////////////////
|
||||
// Public facing API
|
||||
override def findByTxIds(
|
||||
txIds: Vector[DoubleSha256DigestBE]
|
||||
): Future[Vector[TransactionDb]] = {
|
||||
transactionDAO.findByTxIds(txIds)
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
override def processTransaction(
|
||||
|
@ -7,9 +7,14 @@ import org.bitcoins.core.api.chain.ChainQueryApi
|
||||
import org.bitcoins.core.api.wallet.UtxoHandlingApi
|
||||
import org.bitcoins.core.api.wallet.db.*
|
||||
import org.bitcoins.core.consensus.Consensus
|
||||
import org.bitcoins.core.currency.{CurrencyUnit, CurrencyUnits}
|
||||
import org.bitcoins.core.hd.HDAccount
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.script.{P2WPKHWitnessSPKV0, P2WPKHWitnessV0}
|
||||
import org.bitcoins.core.protocol.script.{
|
||||
P2WPKHWitnessSPKV0,
|
||||
P2WPKHWitnessV0,
|
||||
ScriptPubKey
|
||||
}
|
||||
import org.bitcoins.core.protocol.transaction.*
|
||||
import org.bitcoins.core.util.{BlockHashWithConfs, FutureUtil}
|
||||
import org.bitcoins.core.wallet.utxo.*
|
||||
@ -65,6 +70,39 @@ case class UtxoHandling(
|
||||
.map(_ => ())
|
||||
}
|
||||
|
||||
override def findByScriptPubKey(
|
||||
scriptPubKey: ScriptPubKey
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
spendingInfoDAO.findByScriptPubKey(scriptPubKey)
|
||||
}
|
||||
|
||||
override def findByOutPoints(
|
||||
outPoints: Vector[TransactionOutPoint]
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
spendingInfoDAO.findByOutPoints(outPoints)
|
||||
}
|
||||
|
||||
override def findOutputsBeingSpent(
|
||||
tx: Transaction
|
||||
): Future[Vector[SpendingInfoDb]] = {
|
||||
spendingInfoDAO.findOutputsBeingSpent(tx)
|
||||
}
|
||||
|
||||
override def getConfirmedBalance(tag: AddressTag): Future[CurrencyUnit] = {
|
||||
spendingInfoDAO.findAllUnspentForTag(tag).map { allUnspent =>
|
||||
val confirmed = allUnspent.filter(_.state == ConfirmedReceived)
|
||||
confirmed.foldLeft(CurrencyUnits.zero)(_ + _.output.value)
|
||||
}
|
||||
}
|
||||
|
||||
override def getUnconfirmedBalance(tag: AddressTag): Future[CurrencyUnit] = {
|
||||
spendingInfoDAO.findAllUnspentForTag(tag).map { allUnspent =>
|
||||
val confirmed = allUnspent
|
||||
.filter(utxo => TxoState.pendingReceivedStates.contains(utxo.state))
|
||||
confirmed.foldLeft(CurrencyUnits.zero)(_ + _.output.value)
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
override def listUtxos(): Future[Vector[SpendingInfoDb]] = {
|
||||
spendingInfoDAO.findAllUnspent()
|
||||
|
Loading…
Reference in New Issue
Block a user