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, CompactFilterDAO,
CompactFilterHeaderDAO CompactFilterHeaderDAO
} }
import org.bitcoins.core.api.chain.{ChainApi, FilterSyncMarker}
import org.bitcoins.core.api.chain.db.{BlockHeaderDb, CompactFilterHeaderDb} 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.core.protocol.blockchain.BlockHeader
import org.bitcoins.crypto.DoubleSha256DigestBE import org.bitcoins.crypto.DoubleSha256DigestBE

View file

@ -132,6 +132,10 @@ case class CompactFilterDAO()(implicit
val join = table val join = table
.join(blockHeaderTable) .join(blockHeaderTable)
.on(_.blockHash === _.hash) .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 val maxQuery = join.map(_._2.chainWork).max
@ -149,21 +153,12 @@ case class CompactFilterDAO()(implicit
} }
private val bestFilterHeightQuery = { private val bestFilterHeightQuery = {
val join = table bestFilterQuery.map(_.headOption.map(_.height))
.join(blockHeaderTable)
.on(_.blockHash === _.hash)
val maxQuery = join.map(_._2.chainWork).max
join
.filter(_._2.chainWork === maxQuery)
.take(1)
.map(_._1.height)
.result
.transactionally
} }
def getBestFilterHeight: Future[Int] = { 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 val join = table
.join(blockHeaderTable) .join(blockHeaderTable)
.on(_.blockHash === _.hash) .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 val maxQuery = join.map(_._2.chainWork).max
@ -146,22 +150,13 @@ case class CompactFilterHeaderDAO()(implicit
} }
private val bestFilterHeaderHeightQuery = { private val bestFilterHeaderHeightQuery = {
val join = table bestFilterHeaderQuery.map(_.headOption.map(_.height))
.join(blockHeaderTable)
.on(_.blockHash === _.hash)
val maxQuery = join.map(_._2.chainWork).max
join
.filter(_._2.chainWork === maxQuery)
.take(1)
.map(_._1.height)
.result
.transactionally
} }
def getBestFilterHeaderHeight: Future[Int] = { 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 /** This looks for best filter headers whose [[CompactFilterHeaderDb.blockHashBE]] are associated with the given