mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-01-18 21:34:39 +01:00
Increase chain test code coverage even more (#2028)
This commit is contained in:
parent
613f6ba4b9
commit
ae6bab857f
@ -21,6 +21,17 @@ class BlockchainTest extends ChainUnitTest {
|
|||||||
|
|
||||||
behavior of "Blockchain"
|
behavior of "Blockchain"
|
||||||
|
|
||||||
|
it must "have the correct toString" inFixtured {
|
||||||
|
case ChainFixture.Empty =>
|
||||||
|
val genesis = ChainUnitTest.genesisHeaderDb
|
||||||
|
val headerDb =
|
||||||
|
BlockHeaderHelper.buildNextHeader(genesis)
|
||||||
|
val chain = Blockchain(Vector(headerDb, genesis))
|
||||||
|
|
||||||
|
assert(
|
||||||
|
chain.toString == s"BaseBlockchain(tip=$headerDb,last=$genesis,length=2)")
|
||||||
|
}
|
||||||
|
|
||||||
it must "connect a new header to the current tip of a blockchain" inFixtured {
|
it must "connect a new header to the current tip of a blockchain" inFixtured {
|
||||||
case ChainFixture.Empty =>
|
case ChainFixture.Empty =>
|
||||||
val blockchain = Blockchain.fromHeaders(
|
val blockchain = Blockchain.fromHeaders(
|
||||||
|
@ -3,6 +3,7 @@ package org.bitcoins.chain.blockchain
|
|||||||
import org.bitcoins.chain.{ChainCallbacks, OnBlockHeaderConnected}
|
import org.bitcoins.chain.{ChainCallbacks, OnBlockHeaderConnected}
|
||||||
import org.bitcoins.chain.pow.Pow
|
import org.bitcoins.chain.pow.Pow
|
||||||
import org.bitcoins.core.api.chain.ChainApi
|
import org.bitcoins.core.api.chain.ChainApi
|
||||||
|
import org.bitcoins.core.api.chain.ChainQueryApi.FilterResponse
|
||||||
import org.bitcoins.core.api.chain.db.{BlockHeaderDb, BlockHeaderDbHelper}
|
import org.bitcoins.core.api.chain.db.{BlockHeaderDb, BlockHeaderDbHelper}
|
||||||
import org.bitcoins.core.gcs.{BlockFilter, FilterHeader}
|
import org.bitcoins.core.gcs.{BlockFilter, FilterHeader}
|
||||||
import org.bitcoins.core.number.{Int32, UInt32}
|
import org.bitcoins.core.number.{Int32, UInt32}
|
||||||
@ -519,14 +520,40 @@ class ChainHandlerTest extends ChainDbUnitTest {
|
|||||||
bestBlock <- chainHandler.getBestBlockHeader()
|
bestBlock <- chainHandler.getBestBlockHeader()
|
||||||
stamp1 = BlockStamp.BlockHash(bestBlock.hashBE)
|
stamp1 = BlockStamp.BlockHash(bestBlock.hashBE)
|
||||||
stamp2 = BlockStamp.BlockHeight(bestBlock.height)
|
stamp2 = BlockStamp.BlockHeight(bestBlock.height)
|
||||||
stamp3 = BlockStamp.BlockTime(bestBlock.time)
|
|
||||||
height1 <- chainHandler.getHeightByBlockStamp(stamp1)
|
height1 <- chainHandler.getHeightByBlockStamp(stamp1)
|
||||||
height2 <- chainHandler.getHeightByBlockStamp(stamp2)
|
height2 <- chainHandler.getHeightByBlockStamp(stamp2)
|
||||||
// TODO implement BlockTime
|
|
||||||
// height3 <- chainHandler.getHeightByBlockStamp(stamp3)
|
|
||||||
} yield {
|
} yield {
|
||||||
assert(height1 == height2)
|
assert(height1 == height2)
|
||||||
// assert(height1 == height3)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it must "fail to return the height by block time" in {
|
||||||
|
chainHandler: ChainHandler =>
|
||||||
|
recoverToSucceededIf[RuntimeException] {
|
||||||
|
for {
|
||||||
|
bestBlock <- chainHandler.getBestBlockHeader()
|
||||||
|
stamp = BlockStamp.BlockTime(bestBlock.time)
|
||||||
|
height <- chainHandler.getHeightByBlockStamp(stamp)
|
||||||
|
} yield height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it must "fail to return the height by block stamp with an unknown hash" in {
|
||||||
|
chainHandler: ChainHandler =>
|
||||||
|
recoverToSucceededIf[UnknownBlockHash] {
|
||||||
|
val stamp = BlockStamp.BlockHash(DoubleSha256DigestBE.empty)
|
||||||
|
chainHandler.getHeightByBlockStamp(stamp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it must "find filters between heights" in { chainHandler: ChainHandler =>
|
||||||
|
chainHandler.getFiltersBetweenHeights(0, 1).map { filters =>
|
||||||
|
val genesis = ChainUnitTest.genesisFilterDb
|
||||||
|
val genesisFilterResponse = FilterResponse(genesis.golombFilter,
|
||||||
|
genesis.blockHashBE,
|
||||||
|
genesis.height)
|
||||||
|
|
||||||
|
assert(filters == Vector(genesisFilterResponse))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,6 +594,27 @@ class ChainHandlerTest extends ChainDbUnitTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it must "check isMissingChainWork when there is over a 100 headers" in {
|
||||||
|
chainHandler: ChainHandler =>
|
||||||
|
val genesis = ChainUnitTest.genesisHeaderDb
|
||||||
|
val headers = 0.to(101).foldLeft(Vector(genesis)) { (accum, _) =>
|
||||||
|
val next = BlockHeaderHelper.buildNextHeader(accum.last)
|
||||||
|
accum :+ next
|
||||||
|
}
|
||||||
|
|
||||||
|
val noWork = BlockHeaderHelper
|
||||||
|
.buildNextHeader(headers.last)
|
||||||
|
.copy(chainWork = BigInt(0))
|
||||||
|
|
||||||
|
for {
|
||||||
|
_ <- chainHandler.blockHeaderDAO.upsertAll(headers)
|
||||||
|
isMissingFirst100 <- chainHandler.isMissingChainWork
|
||||||
|
_ = assert(!isMissingFirst100)
|
||||||
|
_ <- chainHandler.blockHeaderDAO.create(noWork)
|
||||||
|
isMissingLast100 <- chainHandler.isMissingChainWork
|
||||||
|
} yield assert(isMissingLast100)
|
||||||
|
}
|
||||||
|
|
||||||
it must "process a new valid block header with a callback" in {
|
it must "process a new valid block header with a callback" in {
|
||||||
chainHandler: ChainHandler =>
|
chainHandler: ChainHandler =>
|
||||||
val resultP: Promise[Boolean] = Promise()
|
val resultP: Promise[Boolean] = Promise()
|
||||||
@ -578,7 +626,7 @@ class ChainHandlerTest extends ChainDbUnitTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val callbacks = ChainCallbacks(Vector(callback))
|
val callbacks = ChainCallbacks.onBlockHeaderConnected(callback)
|
||||||
chainHandler.chainConfig.addCallbacks(callbacks)
|
chainHandler.chainConfig.addCallbacks(callbacks)
|
||||||
|
|
||||||
val newValidHeader =
|
val newValidHeader =
|
||||||
|
@ -190,13 +190,18 @@ class MainnetChainHandlerTest extends ChainDbUnitTest {
|
|||||||
ChainTestUtil.blockHeader562462)
|
ChainTestUtil.blockHeader562462)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val noWorkGenesis = genesis.copy(chainWork = BigInt(0))
|
||||||
|
|
||||||
val blockchain =
|
val blockchain =
|
||||||
Blockchain(headersWithNoWork :+ genesis.copy(chainWork = BigInt(0)))
|
Blockchain(headersWithNoWork :+ noWorkGenesis)
|
||||||
|
|
||||||
val chainHandler = tempHandler.copy(blockchains = Vector(blockchain))
|
val chainHandler = tempHandler.copy(blockchains = Vector(blockchain))
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
_ <- chainHandler.blockHeaderDAO.update(noWorkGenesis)
|
||||||
_ <- chainHandler.blockHeaderDAO.createAll(headersWithNoWork)
|
_ <- chainHandler.blockHeaderDAO.createAll(headersWithNoWork)
|
||||||
|
lowestNoWork <- chainHandler.blockHeaderDAO.getLowestNoWorkHeight
|
||||||
|
_ = assert(lowestNoWork == 0)
|
||||||
isMissingWork <- chainHandler.isMissingChainWork
|
isMissingWork <- chainHandler.isMissingChainWork
|
||||||
_ = assert(isMissingWork)
|
_ = assert(isMissingWork)
|
||||||
newHandler <- chainHandler.recalculateChainWork
|
newHandler <- chainHandler.recalculateChainWork
|
||||||
|
@ -37,12 +37,12 @@ object ChainCallbacks {
|
|||||||
override def +(other: ChainCallbacks): ChainCallbacks =
|
override def +(other: ChainCallbacks): ChainCallbacks =
|
||||||
copy(onBlockHeaderConnected =
|
copy(onBlockHeaderConnected =
|
||||||
onBlockHeaderConnected ++ other.onBlockHeaderConnected)
|
onBlockHeaderConnected ++ other.onBlockHeaderConnected)
|
||||||
|
|
||||||
/** Constructs a set of callbacks that only acts on block headers connected */
|
|
||||||
def onBlockHeaderConnected(f: OnBlockHeaderConnected): ChainCallbacks =
|
|
||||||
ChainCallbacks(onBlockHeaderConnected = Vector(f))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Constructs a set of callbacks that only acts on block headers connected */
|
||||||
|
def onBlockHeaderConnected(f: OnBlockHeaderConnected): ChainCallbacks =
|
||||||
|
ChainCallbacks(onBlockHeaderConnected = Vector(f))
|
||||||
|
|
||||||
lazy val empty: ChainCallbacks =
|
lazy val empty: ChainCallbacks =
|
||||||
ChainCallbacks(onBlockHeaderConnected = Vector.empty)
|
ChainCallbacks(onBlockHeaderConnected = Vector.empty)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user