From 48e3cb8e1421d8295b46832a510544b9b3361eed Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Sat, 15 Aug 2020 07:23:26 -0500 Subject: [PATCH] =?UTF-8?q?Attempt=20to=20batch=20checking=20of=20headers?= =?UTF-8?q?=20in=20chainTest=20to=20avoid=20reject=20exe=E2=80=A6=20(#1826?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Attempt to batch checking of headers in chainTest to avoid reject execution exceptions in the scala slick database queue * Fix 2.12 compile issue --- .../bitcoins/chain/pow/BitcoinPowTest.scala | 53 ++++++++++++------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/chain-test/src/test/scala/org/bitcoins/chain/pow/BitcoinPowTest.scala b/chain-test/src/test/scala/org/bitcoins/chain/pow/BitcoinPowTest.scala index 47f47e5b12..ae9f1fad5f 100644 --- a/chain-test/src/test/scala/org/bitcoins/chain/pow/BitcoinPowTest.scala +++ b/chain-test/src/test/scala/org/bitcoins/chain/pow/BitcoinPowTest.scala @@ -3,17 +3,19 @@ package org.bitcoins.chain.pow import akka.actor.ActorSystem import org.bitcoins.chain.blockchain.Blockchain import org.bitcoins.chain.config.ChainAppConfig +import org.bitcoins.chain.models.BlockHeaderDAO import org.bitcoins.core.protocol.blockchain.{ MainNetChainParams, TestNetChainParams } +import org.bitcoins.core.util.FutureUtil import org.bitcoins.testkit.chain.fixture.{ChainFixture, ChainFixtureTag} import org.bitcoins.testkit.chain.{ ChainDbUnitTest, ChainTestUtil, ChainUnitTest } -import org.scalatest.FutureOutcome +import org.scalatest.{Assertion, FutureOutcome} import scala.concurrent.Future @@ -62,24 +64,17 @@ class BitcoinPowTest extends ChainDbUnitTest { case ChainFixture.PopulatedBlockHeaderDAO(blockHeaderDAO) => val iterations = 4200 // We must start after the first POW change to avoid looking for a block we don't have - val assertionFs = - (ChainUnitTest.FIRST_POW_CHANGE + 1 until ChainUnitTest.FIRST_POW_CHANGE + 1 + iterations) - .map { height => - val blockF = blockHeaderDAO.getAtHeight(height).map(_.head) - val blockchainF = - blockF.flatMap(b => blockHeaderDAO.getBlockchainFrom(b)) - val nextBlockF = blockHeaderDAO.getAtHeight(height + 1).map(_.head) + val iterator = + (ChainUnitTest.FIRST_POW_CHANGE + 1) + .until(ChainUnitTest.FIRST_POW_CHANGE + 1 + iterations) + .toVector + val assertionFs: Future[Assertion] = FutureUtil + .batchExecute(elements = iterator, + f = batchCheckHeaderPOW(_: Vector[Int], blockHeaderDAO), + init = succeed, + batchSize = 1000) - for { - blockchain <- blockchainF - nextTip <- nextBlockF - nextNBits = - Pow.getNetworkWorkRequired(nextTip.blockHeader, blockchain) - } yield assert(nextNBits == nextTip.nBits) - } - val seqF = Future.sequence(assertionFs) - - seqF.map(_ => succeed) + assertionFs } it must "getBlockProof correctly for the testnet genesis block" inFixtured { @@ -101,4 +96,26 @@ class BitcoinPowTest extends ChainDbUnitTest { assert(proof == BigInt(4295032833L)) } } + + /** Helper method to check headers proof of work in batches */ + private def batchCheckHeaderPOW( + iterator: Vector[Int], + blockHeaderDAO: BlockHeaderDAO): Future[Assertion] = { + val nestedAssertions: Vector[Future[Assertion]] = { + iterator.map { height => + val blockF = blockHeaderDAO.getAtHeight(height + 1).map(_.head) + val blockchainF = + blockF.flatMap(b => blockHeaderDAO.getBlockchainFrom(b)) + for { + blockchain <- blockchainF + nextTip = blockchain.head + chain = Blockchain.fromHeaders(blockchain.tail.toVector) + nextNBits = Pow.getNetworkWorkRequired(nextTip.blockHeader, chain) + } yield assert(nextNBits == nextTip.nBits) + } + } + Future + .sequence(nestedAssertions) + .map(_ => succeed) + } }