parallelize matching compact filters as this is a bottleneck during IBD (#3137)

* parallelize matching compact filters as this is a bottleneck during IBD

* Use FutureUtil.makeAsync() to actually make it async

* Small optimization, move asmVec outside of lambda so it doesn't need to be re-computed everytime
This commit is contained in:
Chris Stewart 2021-05-25 12:39:39 -05:00 committed by GitHub
parent 41e22b3cbc
commit cea8802c05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -184,21 +184,21 @@ abstract class Wallet
scripts <- spksF
scriptPubKeys =
utxos.flatMap(_.redeemScriptOpt).toSet ++ scripts.map(_.scriptPubKey)
_ <- {
blockHashToDownload <- {
if (scriptPubKeys.isEmpty) {
//do nothing as an optimization, if we have nothing in the wallet
//we don't need to search the filters
Future.unit
Future.successful(Vector.empty)
} else {
FutureUtil.sequentially(blockFilters) {
case (blockHash, blockFilter) =>
val matcher = SimpleFilterMatcher(blockFilter)
if (matcher.matchesAny(scriptPubKeys.toVector.map(_.asmBytes))) {
nodeApi.downloadBlocks(Vector(blockHash))
} else Future.unit
}
FutureUtil
.batchAndParallelExecute(
blockFilters,
searchFilterMatches(scriptPubKeys.toVector)
)
.map(_.flatten)
}
}
_ <- nodeApi.downloadBlocks(blockHashToDownload)
hash = blockFilters.last._1.flip
heightOpt <- heightOptF
_ <- {
@ -216,6 +216,20 @@ abstract class Wallet
}
}
private def searchFilterMatches(spks: Vector[ScriptPubKey])(
blockFilters: Vector[(DoubleSha256Digest, GolombFilter)]): Future[
Vector[DoubleSha256Digest]] = FutureUtil.makeAsync { () =>
val asmVec = spks.map(_.asmBytes)
blockFilters.flatMap { case (blockHash, blockFilter) =>
val matcher = SimpleFilterMatcher(blockFilter)
if (matcher.matchesAny(asmVec)) {
Vector(blockHash)
} else {
Vector.empty
}
}
}
def unlock(
passphraseOpt: Option[AesPassword],
bip39PasswordOpt: Option[String]): Either[