mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 10:46:42 +01:00
Add all wallet outpoints to bloom filter
This is a workaround for Bloom filters never being updated for SegWit. See comment in LockedWallet#getBloomFilter for more context.
This commit is contained in:
parent
efc1ce4405
commit
45a3e93a3d
4 changed files with 69 additions and 27 deletions
|
@ -153,12 +153,17 @@ case class SafeDatabase(config: AppConfig) extends BitcoinSLogger {
|
|||
throw err
|
||||
}
|
||||
|
||||
/** Runs the given DB action */
|
||||
def run[R](action: DBIOAction[R, NoStream, _])(
|
||||
implicit ec: ExecutionContext): Future[R] = {
|
||||
val result = database.run[R](foreignKeysPragma >> action)
|
||||
result.recoverWith { logAndThrowError(action) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given DB sequence-returning DB action
|
||||
* and converts the result to a vector
|
||||
*/
|
||||
def runVec[R](action: DBIOAction[Seq[R], NoStream, _])(
|
||||
implicit ec: ExecutionContext): Future[Vector[R]] = {
|
||||
val result = database.run[Seq[R]](foreignKeysPragma >> action)
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package org.bitcoins.wallet
|
||||
|
||||
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
|
||||
import org.bitcoins.wallet.api.UnlockedWalletApi
|
||||
import org.scalatest.FutureOutcome
|
||||
import org.bitcoins.wallet.api.UnlockWalletError._
|
||||
import org.bitcoins.wallet.api.UnlockWalletSuccess
|
||||
import org.bitcoins.core.util.FutureUtil
|
||||
import org.bitcoins.core.currency._
|
||||
import org.bitcoins.testkit.Implicits._
|
||||
|
||||
class WalletBloomTest extends BitcoinSWalletTest {
|
||||
behavior of "Wallet bloom filter"
|
||||
|
||||
override type FixtureParam = WalletWithBitcoind
|
||||
|
||||
override def withFixture(test: OneArgAsyncTest): FutureOutcome =
|
||||
withNewWalletAndBitcoind(test)
|
||||
|
||||
it should "generate a bloom filter that matches the pubkeys in our wallet" in {
|
||||
param =>
|
||||
val WalletWithBitcoind(walletApi, _) = param
|
||||
val wallet = walletApi.asInstanceOf[Wallet]
|
||||
for {
|
||||
_ <- FutureUtil.sequentially(0 until 10)(_ => wallet.getNewAddress())
|
||||
bloom <- wallet.getBloomFilter()
|
||||
pubkeys <- wallet.listPubkeys()
|
||||
} yield {
|
||||
pubkeys.map { (pub) =>
|
||||
assert(bloom.contains(pub))
|
||||
}.toAssertion
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: change fixture to withFundedWalletAndBitcoind once #577 goes in
|
||||
// https://github.com/bitcoin-s/bitcoin-s/pull/577/files#diff-0fb6ac004fe1e550b7c13258d7d0706cR154
|
||||
it should "generate a bloom filter that matches the outpoints in our wallet" in {
|
||||
param =>
|
||||
val WalletWithBitcoind(walletApi, bitcoind) = param
|
||||
val wallet = walletApi.asInstanceOf[Wallet]
|
||||
|
||||
for {
|
||||
address <- wallet.getNewAddress()
|
||||
tx <- bitcoind
|
||||
.sendToAddress(address, 5.bitcoins)
|
||||
.flatMap(bitcoind.getRawTransaction(_))
|
||||
_ <- wallet.processTransaction(tx.hex, confirmations = 0)
|
||||
outpoints <- wallet.listOutpoints()
|
||||
|
||||
bloom <- wallet.getBloomFilter()
|
||||
} yield {
|
||||
outpoints.map { (out) =>
|
||||
assert(bloom.contains(out))
|
||||
}.toAssertion
|
||||
}
|
||||
}
|
||||
}
|
|
@ -121,33 +121,6 @@ class WalletUnitTest extends BitcoinSWalletTest {
|
|||
} yield res
|
||||
}
|
||||
|
||||
it should "generate a bloom filter" in { walletApi: UnlockedWalletApi =>
|
||||
val wallet = walletApi.asInstanceOf[Wallet]
|
||||
for {
|
||||
_ <- FutureUtil.sequentially(0 until 10)(_ => wallet.getNewAddress())
|
||||
bloom <- wallet.getBloomFilter()
|
||||
pubkeys <- wallet.listPubkeys()
|
||||
} yield {
|
||||
pubkeys.foldLeft(succeed) { (_, pub) =>
|
||||
assert(bloom.contains(pub))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
it should "lock and unlock the wallet" in { wallet: UnlockedWalletApi =>
|
||||
val passphrase = wallet.passphrase
|
||||
val locked = wallet.lock()
|
||||
val unlocked = wallet.unlock(passphrase) match {
|
||||
case MnemonicNotFound => fail(MnemonicNotFound)
|
||||
case BadPassword => fail(BadPassword)
|
||||
case JsonParsingError(message) => fail(message)
|
||||
case UnlockWalletSuccess(unlockedWalletApi) => unlockedWalletApi
|
||||
}
|
||||
|
||||
assert(wallet.mnemonicCode == unlocked.mnemonicCode)
|
||||
}
|
||||
|
||||
it should "fail to unlock the wallet with a bad password" in {
|
||||
wallet: UnlockedWalletApi =>
|
||||
val badpassphrase = AesPassword.fromNonEmptyString("bad")
|
||||
|
|
|
@ -9,6 +9,7 @@ import scala.concurrent.Future
|
|||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.core.crypto.DoubleSha256DigestBE
|
||||
import org.bitcoins.core.protocol.transaction.TransactionOutput
|
||||
import org.bitcoins.core.protocol.transaction.TransactionOutPoint
|
||||
|
||||
case class SpendingInfoDAO()(
|
||||
implicit val ec: ExecutionContext,
|
||||
|
@ -96,4 +97,10 @@ case class SpendingInfoDAO()(
|
|||
|
||||
database.run(query.result).map(_.toVector)
|
||||
}
|
||||
|
||||
/** Enumerates all TX outpoints in the wallet */
|
||||
def findAllOutpoints(): Future[Vector[TransactionOutPoint]] = {
|
||||
val query = table.map(_.outPoint)
|
||||
database.runVec(query.result).map(_.toVector)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue