From d159f3eb5fc8f9df1136d9a94c9228d8a8ff48d1 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Wed, 3 Feb 2021 11:37:36 -0600 Subject: [PATCH] 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 --- .../chain/blockchain/ChainHandlerCached.scala | 2 +- .../chain/models/CompactFilterDAO.scala | 21 +++++++------------ .../chain/models/CompactFilterHeaderDAO.scala | 21 +++++++------------ 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/chain/src/main/scala/org/bitcoins/chain/blockchain/ChainHandlerCached.scala b/chain/src/main/scala/org/bitcoins/chain/blockchain/ChainHandlerCached.scala index 7a648c4468..075a0d06b3 100644 --- a/chain/src/main/scala/org/bitcoins/chain/blockchain/ChainHandlerCached.scala +++ b/chain/src/main/scala/org/bitcoins/chain/blockchain/ChainHandlerCached.scala @@ -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 diff --git a/chain/src/main/scala/org/bitcoins/chain/models/CompactFilterDAO.scala b/chain/src/main/scala/org/bitcoins/chain/models/CompactFilterDAO.scala index 56bbb6874d..a25ca8a033 100644 --- a/chain/src/main/scala/org/bitcoins/chain/models/CompactFilterDAO.scala +++ b/chain/src/main/scala/org/bitcoins/chain/models/CompactFilterDAO.scala @@ -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) + } } } diff --git a/chain/src/main/scala/org/bitcoins/chain/models/CompactFilterHeaderDAO.scala b/chain/src/main/scala/org/bitcoins/chain/models/CompactFilterHeaderDAO.scala index aa2ebbe234..db6a374815 100644 --- a/chain/src/main/scala/org/bitcoins/chain/models/CompactFilterHeaderDAO.scala +++ b/chain/src/main/scala/org/bitcoins/chain/models/CompactFilterHeaderDAO.scala @@ -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