diff --git a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala index 6f075035bd..ac5f833433 100644 --- a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala +++ b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala @@ -37,7 +37,7 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl _ <- peer2.connectToPeers(Set(peer1.node)) _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumber) } yield { - assert(peer1.bl.getBestBlock().hash == peer2.bl.getBestBlock().hash) + assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash) } } @@ -52,7 +52,7 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl _ <- peer2.connectToPeers(Set(peer1.node)) _ <- peer2.waitForRegularSyncLoadLastBlock(blockHeadersPerRequest + 1) } yield { - assert(peer1.bl.getBestBlock().hash == peer2.bl.getBestBlock().hash) + assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash) } } } @@ -72,7 +72,7 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl _ <- peer1.mineNewBlocks(100.milliseconds, 2)(IdentityUpdate) _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumer + 4) } yield { - assert(peer1.bl.getBestBlock().hash == peer2.bl.getBestBlock().hash) + assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash) } } @@ -94,8 +94,8 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumer + 3) } yield { assert( - peer1.bl.getChainWeightByHash(peer1.bl.getBestBlock().hash) == peer2.bl.getChainWeightByHash( - peer2.bl.getBestBlock().hash + peer1.bl.getChainWeightByHash(peer1.bl.getBestBlock().get.hash) == peer2.bl.getChainWeightByHash( + peer2.bl.getBestBlock().get.hash ) ) (peer1.bl.getBlockByNumber(blockNumer + 1), peer2.bl.getBlockByNumber(blockNumer + 1)) match { diff --git a/src/it/scala/io/iohk/ethereum/sync/util/CommonFakePeer.scala b/src/it/scala/io/iohk/ethereum/sync/util/CommonFakePeer.scala index 3468d0f2f8..afba56b079 100644 --- a/src/it/scala/io/iohk/ethereum/sync/util/CommonFakePeer.scala +++ b/src/it/scala/io/iohk/ethereum/sync/util/CommonFakePeer.scala @@ -246,7 +246,7 @@ abstract class CommonFakePeer(peerName: String, fakePeerCustomConfig: FakePeerCu } def getCurrentState(): BlockchainState = { - val bestBlock = bl.getBestBlock() + val bestBlock = bl.getBestBlock().get val currentWorldState = getMptForBlock(bestBlock) val currentWeight = bl.getChainWeightByHash(bestBlock.hash).get BlockchainState(bestBlock, currentWorldState, currentWeight) @@ -301,13 +301,13 @@ abstract class CommonFakePeer(peerName: String, fakePeerCustomConfig: FakePeerCu n: BigInt )(updateWorldForBlock: (BigInt, InMemoryWorldStateProxy) => InMemoryWorldStateProxy): Task[Unit] = { Task(bl.getBestBlock()).flatMap { block => - if (block.number >= n) { + if (block.get.number >= n) { Task(()) } else { Task { - val currentWeight = bl.getChainWeightByHash(block.hash).get - val currentWolrd = getMptForBlock(block) - val (newBlock, newWeight, _) = createChildBlock(block, currentWeight, currentWolrd)(updateWorldForBlock) + val currentWeight = bl.getChainWeightByHash(block.get.hash).get + val currentWolrd = getMptForBlock(block.get) + val (newBlock, newWeight, _) = createChildBlock(block.get, currentWeight, currentWolrd)(updateWorldForBlock) bl.save(newBlock, Seq(), newWeight, saveAsBestBlock = true) broadcastBlock(newBlock, newWeight) }.flatMap(_ => importBlocksUntil(n)(updateWorldForBlock)) diff --git a/src/it/scala/io/iohk/ethereum/sync/util/FastSyncItSpecUtils.scala b/src/it/scala/io/iohk/ethereum/sync/util/FastSyncItSpecUtils.scala index e563286b24..6f83ad037f 100644 --- a/src/it/scala/io/iohk/ethereum/sync/util/FastSyncItSpecUtils.scala +++ b/src/it/scala/io/iohk/ethereum/sync/util/FastSyncItSpecUtils.scala @@ -55,7 +55,7 @@ object FastSyncItSpecUtils { // Reads whole trie into memory, if the trie lacks nodes in storage it will be None def getBestBlockTrie(): Option[MptNode] = { Try { - val bestBlock = bl.getBestBlock() + val bestBlock = bl.getBestBlock().get val bestStateRoot = bestBlock.header.stateRoot MptTraversals.parseTrieIntoMemory( HashNode(bestStateRoot.toArray), @@ -99,7 +99,7 @@ object FastSyncItSpecUtils { def startWithState(): Task[Unit] = { Task { - val currentBest = bl.getBestBlock().header + val currentBest = bl.getBestBlock().get.header val safeTarget = currentBest.number + syncConfig.fastSyncBlockValidationX val nextToValidate = currentBest.number + 1 val syncState = diff --git a/src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala b/src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala index 083ce829d0..abb303518a 100644 --- a/src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala +++ b/src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala @@ -92,7 +92,7 @@ object RegularSyncItSpecUtils { Task(blockNumber match { case Some(bNumber) => bl.getBlockByNumber(bNumber).getOrElse(throw new RuntimeException(s"block by number: $bNumber doesn't exist")) - case None => bl.getBestBlock() + case None => bl.getBestBlock().get }).flatMap { block => Task { val currentWeight = bl @@ -112,7 +112,7 @@ object RegularSyncItSpecUtils { def mineNewBlock( plusDifficulty: BigInt = 0 )(updateWorldForBlock: (BigInt, InMemoryWorldStateProxy) => InMemoryWorldStateProxy): Task[Unit] = Task { - val block: Block = bl.getBestBlock() + val block: Block = bl.getBestBlock().get val currentWeight = bl .getChainWeightByHash(block.hash) .getOrElse(throw new RuntimeException(s"ChainWeight by hash: ${block.hash} doesn't exist")) diff --git a/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala b/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala index 5da2f865b4..21d52d1e82 100644 --- a/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala +++ b/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala @@ -212,7 +212,7 @@ class BlockchainMock(genesisHash: ByteString) extends Blockchain { def saveBestKnownBlocks(bestBlockNumber: BigInt, latestCheckpointNumber: Option[BigInt] = None): Unit = ??? - def getBestBlock(): Block = ??? + def getBestBlock(): Option[Block] = ??? override def save(block: Block, receipts: Seq[Receipt], weight: ChainWeight, saveAsBestBlock: Boolean): Unit = ??? diff --git a/src/main/scala/io/iohk/ethereum/consensus/ethash/EthashBlockCreator.scala b/src/main/scala/io/iohk/ethereum/consensus/ethash/EthashBlockCreator.scala index d2931354b7..a1ff47f316 100644 --- a/src/main/scala/io/iohk/ethereum/consensus/ethash/EthashBlockCreator.scala +++ b/src/main/scala/io/iohk/ethereum/consensus/ethash/EthashBlockCreator.scala @@ -32,8 +32,7 @@ class EthashBlockCreator( withTransactions: Boolean = true, initialWorldStateBeforeExecution: Option[InMemoryWorldStateProxy] = None ): Task[PendingBlockAndState] = { - val transactions = - if (withTransactions) getTransactionsFromPool else Task.now(PendingTransactionsResponse(Nil)) + val transactions = if (withTransactions) getTransactionsFromPool else Task.now(PendingTransactionsResponse(Nil)) Task.parZip2(getOmmersFromPool(parentBlock.hash), transactions).map { case (ommers, pendingTxs) => blockGenerator.generateBlock( parentBlock, diff --git a/src/main/scala/io/iohk/ethereum/consensus/ethash/EthashMiner.scala b/src/main/scala/io/iohk/ethereum/consensus/ethash/EthashMiner.scala index 05348dfa1c..1a90de277c 100644 --- a/src/main/scala/io/iohk/ethereum/consensus/ethash/EthashMiner.scala +++ b/src/main/scala/io/iohk/ethereum/consensus/ethash/EthashMiner.scala @@ -56,39 +56,46 @@ class EthashMiner( } def processMining(): Unit = { - val parentBlock = blockchain.getBestBlock() - val blockNumber = parentBlock.header.number.toLong + 1 - val epoch = EthashUtils.epoch(blockNumber, blockCreator.blockchainConfig.ecip1099BlockNumber.toLong) - val (dag, dagSize) = calculateDagSize(blockNumber, epoch) - - blockCreator - .getBlockForMining(parentBlock) - .map { case PendingBlockAndState(PendingBlock(block, _), _) => - val headerHash = crypto.kec256(BlockHeader.getEncodedWithoutNonce(block.header)) - val startTime = System.nanoTime() - val mineResult = - mine(headerHash, block.header.difficulty.toLong, dagSize, dag, blockCreator.miningConfig.mineRounds) - val time = System.nanoTime() - startTime - //FIXME: consider not reporting hash rate when time delta is zero - val hashRate = if (time > 0) (mineResult.triedHashes.toLong * 1000000000) / time else Long.MaxValue - ethMiningService.submitHashRate(SubmitHashRateRequest(hashRate, ByteString("mantis-miner"))) - mineResult match { - case MiningSuccessful(_, pow, nonce) => - log.info( - s"Mining successful with ${ByteStringUtils.hash2string(pow.mixHash)} and nonce ${ByteStringUtils.hash2string(nonce)}" - ) - syncController ! SyncProtocol.MinedBlock( - block.copy(header = block.header.copy(nonce = nonce, mixHash = pow.mixHash)) - ) - case _ => log.info("Mining unsuccessful") - } - self ! ProcessMining - } - .onErrorHandle { ex => - log.error(ex, "Unable to get block for mining") + blockchain.getBestBlock() match { + case Some(blockValue) => + blockCreator + .getBlockForMining(blockValue) + .map { + case PendingBlockAndState(PendingBlock(block, _), _) => { + val blockNumber = block.header.number.toLong + 1 + val epoch = EthashUtils.epoch(blockNumber, blockCreator.blockchainConfig.ecip1099BlockNumber.toLong) + val (dag, dagSize) = calculateDagSize(blockNumber, epoch) + val headerHash = crypto.kec256(BlockHeader.getEncodedWithoutNonce(block.header)) + val startTime = System.nanoTime() + val mineResult = + mine(headerHash, block.header.difficulty.toLong, dagSize, dag, blockCreator.miningConfig.mineRounds) + val time = System.nanoTime() - startTime + //FIXME: consider not reporting hash rate when time delta is zero + val hashRate = if (time > 0) (mineResult.triedHashes.toLong * 1000000000) / time else Long.MaxValue + ethMiningService.submitHashRate(SubmitHashRateRequest(hashRate, ByteString("mantis-miner"))) + mineResult match { + case MiningSuccessful(_, pow, nonce) => + log.info( + s"Mining successful with ${ByteStringUtils.hash2string(pow.mixHash)} and nonce ${ByteStringUtils.hash2string(nonce)}" + ) + syncController ! SyncProtocol.MinedBlock( + block.copy(header = block.header.copy(nonce = nonce, mixHash = pow.mixHash)) + ) + case _ => log.info("Mining unsuccessful") + } + self ! ProcessMining + } + } + .onErrorHandle { ex => + log.error(ex, "Unable to get block for mining") + context.system.scheduler.scheduleOnce(10.seconds, self, ProcessMining) + } + .runAsyncAndForget + case None => { + log.error("Unable to get block for mining, getBestBlock() returned None") context.system.scheduler.scheduleOnce(10.seconds, self, ProcessMining) } - .runAsyncAndForget + } } private def calculateDagSize(blockNumber: Long, epoch: Long): (Array[Array[Int]], Long) = { diff --git a/src/main/scala/io/iohk/ethereum/consensus/ethash/MockedMiner.scala b/src/main/scala/io/iohk/ethereum/consensus/ethash/MockedMiner.scala index 158eafb6a9..582cd53d3b 100644 --- a/src/main/scala/io/iohk/ethereum/consensus/ethash/MockedMiner.scala +++ b/src/main/scala/io/iohk/ethereum/consensus/ethash/MockedMiner.scala @@ -45,7 +45,7 @@ class MockedMiner( } case None => val parentBlock = blockchain.getBestBlock() - startMiningBlocks(mineBlocks, parentBlock) + startMiningBlocks(mineBlocks, parentBlock.get) } } diff --git a/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala b/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala index 9ba1d6da5a..024ab0b306 100644 --- a/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala +++ b/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala @@ -142,7 +142,7 @@ trait Blockchain { def getBestBlockNumber(): BigInt - def getBestBlock(): Block + def getBestBlock(): Option[Block] def getLatestCheckpointBlockNumber(): BigInt @@ -276,10 +276,10 @@ class BlockchainImpl( override def getLatestCheckpointBlockNumber(): BigInt = bestKnownBlockAndLatestCheckpoint.get().latestCheckpointNumber - override def getBestBlock(): Block = { + override def getBestBlock(): Option[Block] = { val bestBlockNumber = getBestBlockNumber() log.debug("Trying to get best block with number {}", bestBlockNumber) - getBlockByNumber(bestBlockNumber).get + getBlockByNumber(bestBlockNumber) } override def getAccount(address: Address, blockNumber: BigInt): Option[Account] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthMiningService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthMiningService.scala index 7ae09896fc..a4c6d0704b 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthMiningService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthMiningService.scala @@ -78,26 +78,29 @@ class EthMiningService( def getWork(req: GetWorkRequest): ServiceResponse[GetWorkResponse] = consensus.ifEthash(ethash => { reportActive() - val bestBlock = blockchain.getBestBlock() - val response: ServiceResponse[GetWorkResponse] = - Task.parZip2(getOmmersFromPool(bestBlock.hash), getTransactionsFromPool).map { case (ommers, pendingTxs) => - val blockGenerator = ethash.blockGenerator - val PendingBlockAndState(pb, _) = blockGenerator.generateBlock( - bestBlock, - pendingTxs.pendingTransactions.map(_.stx.tx), - consensusConfig.coinbase, - ommers.headers, - None - ) - Right( - GetWorkResponse( - powHeaderHash = ByteString(kec256(BlockHeader.getEncodedWithoutNonce(pb.block.header))), - dagSeed = EthashUtils.seed(pb.block.header.number.toLong), - target = ByteString((BigInt(2).pow(256) / pb.block.header.difficulty).toByteArray) + blockchain.getBestBlock() match { + case Some(block) => + Task.parZip2(getOmmersFromPool(block.hash), getTransactionsFromPool).map { case (ommers, pendingTxs) => + val blockGenerator = ethash.blockGenerator + val PendingBlockAndState(pb, _) = blockGenerator.generateBlock( + block, + pendingTxs.pendingTransactions.map(_.stx.tx), + consensusConfig.coinbase, + ommers.headers, + None ) - ) - } - response + Right( + GetWorkResponse( + powHeaderHash = ByteString(kec256(BlockHeader.getEncodedWithoutNonce(pb.block.header))), + dagSeed = EthashUtils.seed(pb.block.header.number.toLong), + target = ByteString((BigInt(2).pow(256) / pb.block.header.difficulty).toByteArray) + ) + ) + } + case None => + log.error("Getting current best block failed") + Task.now(Left(JsonRpcError.InternalError)) + } })(Task.now(Left(JsonRpcError.ConsensusIsNotEthash))) def submitWork(req: SubmitWorkRequest): ServiceResponse[SubmitWorkResponse] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala index f935aad6b2..6e7c64442a 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/JsonRpcError.scala @@ -43,6 +43,7 @@ object JsonRpcError extends JsonMethodsImplicits { def executionError(reasons: List[EthCustomError]): JsonRpcError = JsonRpcError(3, "Execution error", reasons) val NodeNotFound = executionError(List(EthCustomError.DoesntExist("State node"))) + val BlockNotFound = executionError(List(EthCustomError.DoesntExist("Block"))) // Custom errors based on proposal https://eth.wiki/json-rpc/json-rpc-error-codes-improvement-proposal sealed abstract class EthCustomError private (val code: Int, val message: String) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala index 35f4cb24ab..db1b6d0930 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/QAService.scala @@ -44,11 +44,15 @@ class QAService( def generateCheckpoint( req: GenerateCheckpointRequest ): ServiceResponse[GenerateCheckpointResponse] = { - Task { - val hash = req.blockHash.getOrElse(blockchain.getBestBlock().hash) - val checkpoint = generateCheckpoint(hash, req.privateKeys) - syncController ! NewCheckpoint(hash, checkpoint.signatures) - Right(GenerateCheckpointResponse(checkpoint)) + val hash = req.blockHash.orElse(blockchain.getBestBlock().map(_.hash)) + hash match { + case Some(hashValue) => + Task { + val checkpoint = generateCheckpoint(hashValue, req.privateKeys) + syncController ! NewCheckpoint(hashValue, checkpoint.signatures) + Right(GenerateCheckpointResponse(checkpoint)) + } + case None => Task.now(Left(JsonRpcError.BlockNotFound)) } } diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala index 67564ef83d..f2a2445988 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala @@ -112,7 +112,7 @@ class TestService( def mineBlocks(request: MineBlocksRequest): ServiceResponse[MineBlocksResponse] = { def mineBlock(): Task[Unit] = { - getBlockForMining(blockchain.getBestBlock()).map { blockForMining => + getBlockForMining(blockchain.getBestBlock().get).map { blockForMining => val res = testLedgerWrapper.ledger.importBlock(blockForMining.block) log.info("Block mining result: " + res) pendingTransactionsManager ! PendingTransactionsManager.ClearPendingTransactions diff --git a/src/main/scala/io/iohk/ethereum/ledger/Ledger.scala b/src/main/scala/io/iohk/ethereum/ledger/Ledger.scala index 4f8160124a..dd063b34f5 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/Ledger.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/Ledger.scala @@ -119,31 +119,32 @@ class LedgerImpl( override def importBlock( block: Block - )(implicit blockExecutionScheduler: Scheduler): Task[BlockImportResult] = { - - val currentBestBlock = blockchain.getBestBlock() - - if (isBlockADuplicate(block.header, currentBestBlock.header.number)) { - Task(log.debug(s"Ignoring duplicate block: (${block.idTag})")) - .map(_ => DuplicateBlock) - } else { - val hash = currentBestBlock.header.hash - blockchain.getChainWeightByHash(hash) match { - case Some(weight) => - val importResult = if (isPossibleNewBestBlock(block.header, currentBestBlock.header)) { - blockImport.importToTop(block, currentBestBlock, weight) - } else { - blockImport.reorganise(block, currentBestBlock, weight) + )(implicit blockExecutionScheduler: Scheduler): Task[BlockImportResult] = + blockchain.getBestBlock() match { + case Some(bestBlock) => + if (isBlockADuplicate(block.header, bestBlock.header.number)) { + Task(log.debug(s"Ignoring duplicate block: (${block.idTag})")) + .map(_ => DuplicateBlock) + } else { + val hash = bestBlock.header.hash + blockchain.getChainWeightByHash(hash) match { + case Some(weight) => + val importResult = if (isPossibleNewBestBlock(block.header, bestBlock.header)) { + blockImport.importToTop(block, bestBlock, weight) + } else { + blockImport.reorganise(block, bestBlock, weight) + } + importResult.foreach(measureBlockMetrics) + importResult + case None => + log.error(s"Getting total difficulty for current best block with hash: $hash failed") + Task.now(BlockImportFailed(s"Couldn't get total difficulty for current best block with hash: $hash")) } - importResult.foreach(measureBlockMetrics) - importResult - - case None => - Task.now(BlockImportFailed(s"Couldn't get total difficulty for current best block with hash: $hash")) - - } + } + case None => + log.error("Getting current best block failed") + Task.now(BlockImportFailed(s"Couldn't find the current best block")) } - } private def isBlockADuplicate(block: BlockHeader, currentBestBlockNumber: BigInt): Boolean = { val hash = block.hash diff --git a/src/test/scala/io/iohk/ethereum/consensus/BlockGeneratorSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/BlockGeneratorSpec.scala index 4e6af195dd..dfa887de0d 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/BlockGeneratorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/BlockGeneratorSpec.scala @@ -29,7 +29,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper "BlockGenerator" should "generate correct block with empty transactions" in new TestSetup { val pendingBlock = - blockGenerator.generateBlock(bestBlock, Nil, Address(testAddress), blockGenerator.emptyX, None).pendingBlock + blockGenerator.generateBlock(bestBlock.get, Nil, Address(testAddress), blockGenerator.emptyX, None).pendingBlock //mined with mantis + ethminer val minedNonce = ByteString(Hex.decode("eb49a2da108d63de")) @@ -55,7 +55,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper it should "generate correct block with transactions" in new TestSetup { val pendingBlock = blockGenerator - .generateBlock(bestBlock, Seq(signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, None) + .generateBlock(bestBlock.get, Seq(signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, None) .pendingBlock //mined with mantis + ethminer @@ -82,7 +82,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper it should "be possible to simulate transaction, on world returned with pending block" in new TestSetup { val pendingBlock = blockGenerator - .generateBlock(bestBlock, Seq(signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, None) + .generateBlock(bestBlock.get, Seq(signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, None) .pendingBlock //mined with mantis + ethminer @@ -104,7 +104,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper // Create new pending block, with updated stateRootHash val pendBlockAndState = blockGenerator.generateBlock( - blockchain.getBestBlock(), + blockchain.getBestBlock().get, Seq(signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, @@ -131,7 +131,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val pendingBlock = blockGenerator .generateBlock( - bestBlock, + bestBlock.get, Seq(signedTransaction.tx, duplicatedSignedTransaction.tx), Address(testAddress), blockGenerator.emptyX, @@ -174,7 +174,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val transactions = Seq(txWitGasTooBigGasLimit, signedTransaction.tx, duplicatedSignedTransaction.tx) val pendingBlock = blockGenerator - .generateBlock(bestBlock, transactions, Address(testAddress), blockGenerator.emptyX, None) + .generateBlock(bestBlock.get, transactions, Address(testAddress), blockGenerator.emptyX, None) .pendingBlock //mined with mantis + ethminer @@ -246,7 +246,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val pendingBlock = blockGenerator - .generateBlock(bestBlock, Seq(generalTx, specificTx), Address(testAddress), blockGenerator.emptyX, None) + .generateBlock(bestBlock.get, Seq(generalTx, specificTx), Address(testAddress), blockGenerator.emptyX, None) .pendingBlock //mined with mantis + ethminer @@ -324,7 +324,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val generatedBlock = blockGenerator - .generateBlock(bestBlock, Seq(generalTx), Address(testAddress), blockGenerator.emptyX, None) + .generateBlock(bestBlock.get, Seq(generalTx), Address(testAddress), blockGenerator.emptyX, None) .pendingBlock blockExecution.executeAndValidateBlock(generatedBlock.block, true) shouldBe a[Right[_, Seq[Receipt]]] @@ -336,7 +336,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val pendingBlock = blockGenerator .generateBlock( - bestBlock, + bestBlock.get, Seq(generalTx, signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, @@ -373,7 +373,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val pendingBlock = blockGenerator .generateBlock( - bestBlock, + bestBlock.get, Seq(nextTransaction, signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, @@ -424,7 +424,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val pendingBlock = blockGenerator .generateBlock( - bestBlock, + bestBlock.get, Seq(nextTransaction, signedFailingTransaction, signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, @@ -461,7 +461,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper val pendingBlock = blockGenerator .generateBlock( - bestBlock, + bestBlock.get, Seq(txWitSameNonceButLowerGasPrice, signedTransaction.tx), Address(testAddress), blockGenerator.emptyX, @@ -520,7 +520,7 @@ class BlockGeneratorSpec extends AnyFlatSpec with Matchers with ScalaCheckProper (blockchainConfig.ecip1097BlockNumber + blockchainConfig.ecip1098BlockNumber) / 2 else blockchainConfig.ecip1098BlockNumber / 2 - val parentBlock = bestBlock.copy(header = bestBlock.header.copy(number = blockNumber - 1)) + val parentBlock = bestBlock.get.copy(header = bestBlock.get.header.copy(number = blockNumber - 1)) val generatedBlock = blockGenerator.generateBlock(parentBlock, Nil, Address(testAddress), blockGenerator.emptyX, None).pendingBlock diff --git a/src/test/scala/io/iohk/ethereum/consensus/ethash/EthashMinerSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/ethash/EthashMinerSpec.scala index 0d03a54ae6..a61939e30c 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/ethash/EthashMinerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/ethash/EthashMinerSpec.scala @@ -35,7 +35,7 @@ class EthashMinerSpec val parent = origin val bfm = blockForMining(parent.header) - (blockchain.getBestBlock _).expects().returns(parent).anyNumberOfTimes() + (blockchain.getBestBlock _).expects().returns(Some(parent)).anyNumberOfTimes() (ethMiningService.submitHashRate _) .expects(*) .returns(Task.now(Right(SubmitHashRateResponse(true)))) diff --git a/src/test/scala/io/iohk/ethereum/consensus/ethash/MockedMinerSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/ethash/MockedMinerSpec.scala index 55e2b45c82..4d051e7169 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/ethash/MockedMinerSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/ethash/MockedMinerSpec.scala @@ -219,7 +219,7 @@ class MockedMinerSpec ) ) - (blockchain.getBestBlock _).expects().returns(origin) + (blockchain.getBestBlock _).expects().returns(Some(origin)) def validateBlock(block: Block, parent: Block, txs: Seq[SignedTransaction] = Seq.empty): Assertion = { block.body.transactionList shouldBe txs diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala index dd1eef43c5..86ee8132af 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/QAServiceSpec.scala @@ -63,7 +63,7 @@ class QAServiceSpec val reqWithoutBlockHash = req.copy(blockHash = None) (blockchain.getBestBlock _) .expects() - .returning(block) + .returning(Some(block)) .once() val result: ServiceResponse[GenerateCheckpointResponse] = diff --git a/src/test/scala/io/iohk/ethereum/ledger/BlockImportSpec.scala b/src/test/scala/io/iohk/ethereum/ledger/BlockImportSpec.scala index 8a41dc7be1..091d1e7036 100644 --- a/src/test/scala/io/iohk/ethereum/ledger/BlockImportSpec.scala +++ b/src/test/scala/io/iohk/ethereum/ledger/BlockImportSpec.scala @@ -139,7 +139,7 @@ class BlockImportSpec extends AnyFlatSpec with Matchers with ScalaFutures { blockchain.save(blockData2.block, blockData2.receipts, blockData2.weight, saveAsBestBlock = true) blockchain.save(blockData3.block, blockData3.receipts, blockData3.weight, saveAsBestBlock = true) - blockchain.getBestBlock() shouldEqual newBlock3 + blockchain.getBestBlock().get shouldEqual newBlock3 blockchain.getChainWeightByHash(newBlock3.header.hash) shouldEqual Some(newWeight3) blockQueue.isQueued(oldBlock2.header.hash) shouldBe true @@ -179,7 +179,7 @@ class BlockImportSpec extends AnyFlatSpec with Matchers with ScalaFutures { whenReady(ledgerWithMockedBlockExecution.importBlock(newBlock3).runToFuture) { _ shouldEqual BlockEnqueued } whenReady(ledgerWithMockedBlockExecution.importBlock(newBlock2).runToFuture) { _ shouldBe a[BlockImportFailed] } - blockchain.getBestBlock() shouldEqual oldBlock3 + blockchain.getBestBlock().get shouldEqual oldBlock3 blockchain.getChainWeightByHash(oldBlock3.header.hash) shouldEqual Some(oldWeight3) blockQueue.isQueued(newBlock2.header.hash) shouldBe true @@ -288,7 +288,7 @@ class BlockImportSpec extends AnyFlatSpec with Matchers with ScalaFutures { blockchain.save(blockData2.block, blockData2.receipts, blockData2.weight, saveAsBestBlock = true) blockchain.save(blockData3.block, blockData3.receipts, blockData3.weight, saveAsBestBlock = true) - blockchain.getBestBlock() shouldEqual newBlock3WithOmmer + blockchain.getBestBlock().get shouldEqual newBlock3WithOmmer } it should "correctly import a checkpoint block" in new EphemBlockchain with CheckpointHelpers { @@ -318,7 +318,7 @@ class BlockImportSpec extends AnyFlatSpec with Matchers with ScalaFutures { // Saving new blocks, because it's part of executeBlocks method mechanism blockchain.save(checkpointBlock, Nil, weightCheckpoint, saveAsBestBlock = true) - blockchain.getBestBlock() shouldEqual checkpointBlock + blockchain.getBestBlock().get shouldEqual checkpointBlock blockchain.getChainWeightByHash(checkpointBlock.hash) shouldEqual Some(weightCheckpoint) } @@ -337,7 +337,7 @@ class BlockImportSpec extends AnyFlatSpec with Matchers with ScalaFutures { whenReady(ledgerWithMockedBlockExecution.importBlock(regularBlock).runToFuture)(_ shouldEqual BlockEnqueued) - blockchain.getBestBlock() shouldEqual checkpointBlock + blockchain.getBestBlock().get shouldEqual checkpointBlock } trait ImportBlockTestSetup extends TestSetupWithVmAndValidators with MockBlockchain diff --git a/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala b/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala index cc4516ba4b..56c5e3a27c 100644 --- a/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala +++ b/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala @@ -368,7 +368,7 @@ trait MockBlockchain extends MockFactory { self: TestSetupWithVmAndValidators => } def setBestBlock(block: Block): CallHandler0[BigInt] = { - (blockchain.getBestBlock _).expects().returning(block) + (blockchain.getBestBlock _).expects().returning(Some(block)) (blockchain.getBestBlockNumber _).expects().anyNumberOfTimes().returning(block.header.number) }