Reduce number of rows selected by best filter header/best filter query (#2617)

* Reduce number of rows selected by best filter header/best filter query

* Remove benchmarking code

* use same queries for best height and best filter so we don't repeat ourselves

* join by blockhash

* Apply optimization to compact filter table

Co-authored-by: Ben Carman <benthecarman@live.com>
This commit is contained in:
Chris Stewart 2021-02-03 11:37:36 -06:00 committed by GitHub
parent 865f1a6d46
commit d159f3eb5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 27 deletions

View file

@ -6,8 +6,8 @@ import org.bitcoins.chain.models.{
CompactFilterDAO,
CompactFilterHeaderDAO
}
import org.bitcoins.core.api.chain.{ChainApi, FilterSyncMarker}
import org.bitcoins.core.api.chain.db.{BlockHeaderDb, CompactFilterHeaderDb}
import org.bitcoins.core.api.chain.{ChainApi, FilterSyncMarker}
import org.bitcoins.core.protocol.blockchain.BlockHeader
import org.bitcoins.crypto.DoubleSha256DigestBE

View file

@ -132,6 +132,10 @@ case class CompactFilterDAO()(implicit
val join = table
.join(blockHeaderTable)
.on(_.blockHash === _.hash)
.sortBy(_._1.height.desc)
//just take the last 2016 headers, if we have a reorg larger than
//this we will not be able to retrieve that header
.take(appConfig.chain.difficultyChangeInterval)
val maxQuery = join.map(_._2.chainWork).max
@ -149,21 +153,12 @@ case class CompactFilterDAO()(implicit
}
private val bestFilterHeightQuery = {
val join = table
.join(blockHeaderTable)
.on(_.blockHash === _.hash)
val maxQuery = join.map(_._2.chainWork).max
join
.filter(_._2.chainWork === maxQuery)
.take(1)
.map(_._1.height)
.result
.transactionally
bestFilterQuery.map(_.headOption.map(_.height))
}
def getBestFilterHeight: Future[Int] = {
safeDatabase.run(bestFilterHeightQuery).map(_.headOption.getOrElse(0))
safeDatabase.run(bestFilterHeightQuery).map { filterHeightOpt =>
filterHeightOpt.headOption.getOrElse(0)
}
}
}

View file

@ -125,6 +125,10 @@ case class CompactFilterHeaderDAO()(implicit
val join = table
.join(blockHeaderTable)
.on(_.blockHash === _.hash)
.sortBy(_._1.height.desc)
//just take the last 2016 headers, if we have a reorg larger than
//this we will not be able to retrieve that header
.take(appConfig.chain.difficultyChangeInterval)
val maxQuery = join.map(_._2.chainWork).max
@ -146,22 +150,13 @@ case class CompactFilterHeaderDAO()(implicit
}
private val bestFilterHeaderHeightQuery = {
val join = table
.join(blockHeaderTable)
.on(_.blockHash === _.hash)
val maxQuery = join.map(_._2.chainWork).max
join
.filter(_._2.chainWork === maxQuery)
.take(1)
.map(_._1.height)
.result
.transactionally
bestFilterHeaderQuery.map(_.headOption.map(_.height))
}
def getBestFilterHeaderHeight: Future[Int] = {
safeDatabase.run(bestFilterHeaderHeightQuery).map(_.headOption.getOrElse(0))
safeDatabase.run(bestFilterHeaderHeightQuery).map { filterHeaderHeightOpt =>
filterHeaderHeightOpt.headOption.getOrElse(0)
}
}
/** This looks for best filter headers whose [[CompactFilterHeaderDb.blockHashBE]] are associated with the given