diff --git a/testkit/src/main/scala/org/bitcoins/testkit/wallet/WalletTestUtil.scala b/testkit/src/main/scala/org/bitcoins/testkit/wallet/WalletTestUtil.scala index fc760da9b9..ebf8f04e9f 100644 --- a/testkit/src/main/scala/org/bitcoins/testkit/wallet/WalletTestUtil.scala +++ b/testkit/src/main/scala/org/bitcoins/testkit/wallet/WalletTestUtil.scala @@ -80,7 +80,8 @@ object WalletTestUtil { outPoint = outpoint, output = output, privKeyPath = privkeyPath, - scriptWitness = scriptWitness) + scriptWitness = scriptWitness, + incomingTxId = None) } lazy val sampleLegacyUtxo = { @@ -91,7 +92,8 @@ object WalletTestUtil { LegacyUTXOSpendingInfoDb(id = None, outPoint = outpoint, output = output, - privKeyPath = privKeyPath) + privKeyPath = privKeyPath, + incomingTxId = None) } lazy val sampleScriptWitness: ScriptWitness = P2WPKHWitnessV0(freshXpub.key) } diff --git a/wallet/src/main/scala/org/bitcoins/wallet/models/TransactionTable.scala b/wallet/src/main/scala/org/bitcoins/wallet/models/TransactionTable.scala index 9a7f97b46a..4da8112847 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/models/TransactionTable.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/models/TransactionTable.scala @@ -59,6 +59,7 @@ final case class IncomingTransactionTable(tag: Tag) // TODO: What happens if we get paid to multiple SPKs in the same // transaction? Need to make a table of SPKs, and map IDs in that // table to TXs in this table... + /** The SPK that's relevant to us in this transaction. Foreign key into address table */ def scriptPubKey: Rep[ScriptPubKey] = column("our_script_pubkey") def fk_scriptPubKey = diff --git a/wallet/src/main/scala/org/bitcoins/wallet/models/UTXOSpendingInfoDAO.scala b/wallet/src/main/scala/org/bitcoins/wallet/models/UTXOSpendingInfoDAO.scala index 389a3046ba..865337b929 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/models/UTXOSpendingInfoDAO.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/models/UTXOSpendingInfoDAO.scala @@ -4,7 +4,6 @@ import org.bitcoins.db.CRUDAutoInc import org.bitcoins.wallet.config._ import slick.jdbc.SQLiteProfile.api._ -import scala.concurrent.Future import scala.concurrent.ExecutionContext case class UTXOSpendingInfoDAO()( @@ -14,7 +13,4 @@ case class UTXOSpendingInfoDAO()( /** The table inside our database we are inserting into */ override val table = TableQuery[UTXOSpendingInfoTable] - - def findAllUTXOs(): Future[Vector[UTXOSpendingInfoDb]] = - database.run(table.result).map(_.toVector) } diff --git a/wallet/src/main/scala/org/bitcoins/wallet/models/UTXOSpendingInfoTable.scala b/wallet/src/main/scala/org/bitcoins/wallet/models/UTXOSpendingInfoTable.scala index b60decc200..cdc4111f0b 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/models/UTXOSpendingInfoTable.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/models/UTXOSpendingInfoTable.scala @@ -28,7 +28,8 @@ case class NativeV0UTXOSpendingInfoDb( outPoint: TransactionOutPoint, output: TransactionOutput, privKeyPath: SegWitHDPath, - scriptWitness: ScriptWitness + scriptWitness: ScriptWitness, + incomingTxId: Option[Long] ) extends UTXOSpendingInfoDb { override val redeemScriptOpt: Option[ScriptPubKey] = None override val scriptWitnessOpt: Option[ScriptWitness] = Some(scriptWitness) @@ -43,7 +44,8 @@ case class LegacyUTXOSpendingInfoDb( id: Option[Long], outPoint: TransactionOutPoint, output: TransactionOutput, - privKeyPath: LegacyHDPath + privKeyPath: LegacyHDPath, + incomingTxId: Option[Long] ) extends UTXOSpendingInfoDb { override val redeemScriptOpt: Option[ScriptPubKey] = None override def scriptWitnessOpt: Option[ScriptWitness] = None @@ -80,6 +82,9 @@ sealed trait UTXOSpendingInfoDb def value: CurrencyUnit = output.value + /** The ID of the transaction this UTXO was received in */ + def incomingTxId: Option[Long] + /** Converts a non-sensitive DB representation of a UTXO into * a signable (and sensitive) real-world UTXO */ @@ -129,13 +134,25 @@ case class UTXOSpendingInfoTable(tag: Tag) def scriptWitnessOpt: Rep[Option[ScriptWitness]] = column[Option[ScriptWitness]]("script_witness") + /** The ID of the incoming transaction corresponding to this UTXO */ + def incomingTxId: Rep[Long] = column("incoming_tx_id") + + def fk_incomingTx = + foreignKey("fk_incoming_tx", + sourceColumns = incomingTxId, + targetTableQuery = TableQuery[IncomingTransactionTable]) { + _.id + } + private type UTXOTuple = ( Option[Long], TransactionOutPoint, TransactionOutput, HDPath, Option[ScriptPubKey], - Option[ScriptWitness]) + Option[ScriptWitness], + Option[Long] // incoming TX ID + ) private val fromTuple: UTXOTuple => UTXOSpendingInfoDb = { case (id, @@ -143,21 +160,27 @@ case class UTXOSpendingInfoTable(tag: Tag) output, path: SegWitHDPath, None, // ReedemScript - Some(scriptWitness)) => - NativeV0UTXOSpendingInfoDb(id, outpoint, output, path, scriptWitness) + Some(scriptWitness), + txId) => + NativeV0UTXOSpendingInfoDb(id, + outpoint, + output, + path, + scriptWitness, + txId) case (id, outpoint, output, path: LegacyHDPath, None, // RedeemScript - None // ScriptWitness - ) => - LegacyUTXOSpendingInfoDb(id, outpoint, output, path) - case (id, outpoint, output, path, spkOpt, swOpt) => + None, // ScriptWitness + txId) => + LegacyUTXOSpendingInfoDb(id, outpoint, output, path, txId) + case (id, outpoint, output, path, spkOpt, swOpt, txId) => throw new IllegalArgumentException( "Could not construct UtxoSpendingInfoDb from bad tuple:" - + s" ($id, $outpoint, $output, $path, $spkOpt, $swOpt) . Note: Nested Segwit is not implemented") + + s" ($id, $outpoint, $output, $path, $spkOpt, $swOpt, $txId) . Note: Nested Segwit is not implemented") } @@ -169,8 +192,15 @@ case class UTXOSpendingInfoTable(tag: Tag) utxo.output, utxo.privKeyPath, utxo.redeemScriptOpt, - utxo.scriptWitnessOpt)) + utxo.scriptWitnessOpt, + utxo.incomingTxId)) def * : ProvenShape[UTXOSpendingInfoDb] = - (id.?, outPoint, output, privKeyPath, redeemScriptOpt, scriptWitnessOpt) <> (fromTuple, toTuple) + (id.?, + outPoint, + output, + privKeyPath, + redeemScriptOpt, + scriptWitnessOpt, + incomingTxId.?) <> (fromTuple, toTuple) }