From 76c61901a384ad6c8857cdadb9e8503da60ccbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Wed, 30 Jun 2021 09:50:14 +0200 Subject: [PATCH 1/9] create BlockchainBranch class with getBlockByNumber and getHashByBlockNumber functions --- .../ethereum/domain/BlockchainReader.scala | 9 +++++ .../domain/branch/BestBlockchainBranch.scala | 37 +++++++++++++++++++ .../domain/branch/BlockchainBranch.scala | 16 ++++++++ 3 files changed, 62 insertions(+) create mode 100644 src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala create mode 100644 src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala diff --git a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala index 9fec95a4a8..279f44b018 100644 --- a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala +++ b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala @@ -8,6 +8,8 @@ import io.iohk.ethereum.db.storage.BlockHeadersStorage import io.iohk.ethereum.db.storage.BlockNumberMappingStorage import io.iohk.ethereum.db.storage.ReceiptStorage import io.iohk.ethereum.db.storage.StateStorage +import io.iohk.ethereum.domain.branch.BestBlockchainBranch +import io.iohk.ethereum.domain.branch.BlockchainBranch import io.iohk.ethereum.mpt.MptNode import io.iohk.ethereum.utils.Logger @@ -86,6 +88,13 @@ class BlockchainReader( */ def getReceiptsByHash(blockhash: ByteString): Option[Seq[Receipt]] = receiptStorage.get(blockhash) + def getBestBranch(): BlockchainBranch = + new BestBlockchainBranch( + getBestBlock().map(_.header).getOrElse(genesisHeader), + blockNumberMappingStorage, + this + ) + def getBestBlockNumber(): BigInt = { val bestSavedBlockNumber = appStateStorage.getBestBlockNumber() val bestKnownBlockNumber = blockchainMetadata.bestKnownBlockAndLatestCheckpoint.get().bestBlockNumber diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala new file mode 100644 index 0000000000..3cabd8fdb5 --- /dev/null +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala @@ -0,0 +1,37 @@ +package io.iohk.ethereum.domain.branch +import akka.util.ByteString + +import io.iohk.ethereum.db.storage.BlockNumberMappingStorage +import io.iohk.ethereum.domain.Block +import io.iohk.ethereum.domain.BlockHeader +import io.iohk.ethereum.domain.BlockchainReader + +/** A Branch instance which only works for the best canonical branch. As this branch + * currently has specific indexes (particularly regarding accessing blocks by number), + * it will uses thoses to provide better performance. + */ +class BestBlockchainBranch( + tipBlockHeader: BlockHeader, + bestChainBlockNumberMappingStorage: BlockNumberMappingStorage, + blockchainReader: BlockchainReader +) extends BlockchainBranch { + + /* The following assumptions are made in this class : + * - the whole branch exist in storage + * - The various metadata and index are consistent + * + * If those assumptions are found to be false, then the application is in an inconsistent + * state and the class will throw. + * */ + + override def getBlockByNumber(number: BigInt): Option[Block] = + if (tipBlockHeader.number <= number && number > 0) { + for { + hash <- blockchainReader.getHashByBlockNumber(number) + block <- blockchainReader.getBlockByHash(hash) + } yield block + } else None + + override def getHashByBlockNumber(number: BigInt): Option[ByteString] = + bestChainBlockNumberMappingStorage.get(number) +} diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala new file mode 100644 index 0000000000..f647f4620e --- /dev/null +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala @@ -0,0 +1,16 @@ +package io.iohk.ethereum.domain.branch + +import akka.util.ByteString + +import io.iohk.ethereum.domain.Block + +// TODO choose a name : ChainInstance, BlockchainBranch, Branch, Blockchain ? +trait BlockchainBranch { + + /** Returns a block inside this branch based on its number */ + def getBlockByNumber(number: BigInt): Option[Block] + + /** Returns a block hash for the block at the given height if any */ + def getHashByBlockNumber(number: BigInt): Option[ByteString] + +} From de98734ceab7421e08c3616d662dfb5bb0265a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Tue, 6 Jul 2021 09:29:57 +0200 Subject: [PATCH 2/9] make getBlockByNumber private in blockchain reader --- .../pow/validators/OmmersValidator.scala | 2 +- .../io/iohk/ethereum/domain/Blockchain.scala | 6 +-- .../ethereum/domain/BlockchainReader.scala | 40 +++++++++---------- .../domain/branch/BestBlockchainBranch.scala | 2 +- .../jsonrpc/CheckpointingService.scala | 2 +- .../ethereum/jsonrpc/EthProofService.scala | 2 +- .../iohk/ethereum/jsonrpc/EthTxService.scala | 2 +- .../iohk/ethereum/jsonrpc/ResolveBlock.scala | 2 +- .../iohk/ethereum/jsonrpc/TestService.scala | 7 +++- .../io/iohk/ethereum/ledger/BlockImport.scala | 2 +- .../ethereum/ledger/BlockValidation.scala | 3 +- .../ethereum/ledger/BranchResolution.scala | 2 +- .../testmode/TestEthBlockServiceWrapper.scala | 3 +- .../TransactionHistoryService.scala | 2 +- 14 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala b/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala index 95705408e6..c9ad4b6383 100644 --- a/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala +++ b/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala @@ -30,7 +30,7 @@ trait OmmersValidator { val getBlockHeaderByHash: ByteString => Option[BlockHeader] = blockchainReader.getBlockHeaderByHash val getNBlocksBack: (ByteString, Int) => List[Block] = - (_, n) => ((blockNumber - n) until blockNumber).toList.flatMap(blockchainReader.getBlockByNumber) + (_, n) => ((blockNumber - n) until blockNumber).toList.flatMap(blockchainReader.getBestBranch.getBlockByNumber) validate(parentHash, blockNumber, ommers, getBlockHeaderByHash, getNBlocksBack) } diff --git a/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala b/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala index e2e222ab1d..2d3fb2d19b 100644 --- a/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala +++ b/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala @@ -103,7 +103,7 @@ class BlockchainImpl( override def isInChain(hash: ByteString): Boolean = (for { header <- blockchainReader.getBlockHeaderByHash(hash) if header.number <= blockchainReader.getBestBlockNumber() - hash <- blockchainReader.getHashByBlockNumber(header.number) + hash <- blockchainReader.getBestBranch().getHashByBlockNumber(header.number) } yield header.hash == hash).getOrElse(false) override def getChainWeightByHash(blockhash: ByteString): Option[ChainWeight] = chainWeightStorage.get(blockhash) @@ -223,7 +223,7 @@ class BlockchainImpl( val latestCheckpointNumber = getLatestCheckpointBlockNumber() val blockNumberMappingUpdates = - if (blockchainReader.getHashByBlockNumber(block.number).contains(blockHash)) + if (blockchainReader.getBestBranch().getHashByBlockNumber(block.number).contains(blockHash)) removeBlockNumberMapping(block.number) else blockNumberMappingStorage.emptyBatchUpdate @@ -292,7 +292,7 @@ class BlockchainImpl( ): BigInt = if (blockNumberToCheck > 0) { val maybePreviousCheckpointBlockNumber = for { - currentBlock <- blockchainReader.getBlockByNumber(blockNumberToCheck) + currentBlock <- blockchainReader.getBestBranch.getBlockByNumber(blockNumberToCheck) if currentBlock.hasCheckpoint && currentBlock.number < latestCheckpointBlockNumber } yield currentBlock.number diff --git a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala index 279f44b018..0ff9f59ffa 100644 --- a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala +++ b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala @@ -50,31 +50,12 @@ class BlockchainReader( body <- getBlockBodyByHash(hash) } yield Block(header, body) - /** Returns a block hash given a block number - * - * @param number Number of the searchead block - * @return Block hash if found - */ - def getHashByBlockNumber(number: BigInt): Option[ByteString] = - blockNumberMappingStorage.get(number) - def getBlockHeaderByNumber(number: BigInt): Option[BlockHeader] = for { hash <- getHashByBlockNumber(number) header <- getBlockHeaderByHash(hash) } yield header - /** Allows to query for a block based on it's number - * - * @param number Block number - * @return Block if it exists - */ - def getBlockByNumber(number: BigInt): Option[Block] = - for { - hash <- getHashByBlockNumber(number) - block <- getBlockByHash(hash) - } yield block - /** Returns MPT node searched by it's hash * @param hash Node Hash * @return MPT node @@ -124,7 +105,26 @@ class BlockchainReader( getBlockHeaderByNumber(0).get def genesisBlock: Block = - getBlockByNumber(0).get + getBestBranch().getBlockByNumber(0).get + + /** Allows to query for a block based on it's number + * + * @param number Block number + * @return Block if it exists + */ + private def getBlockByNumber(number: BigInt): Option[Block] = + for { + hash <- getHashByBlockNumber(number) + block <- getBlockByHash(hash) + } yield block + + /** Returns a block hash given a block number + * + * @param number Number of the searchead block + * @return Block hash if found + */ + private def getHashByBlockNumber(number: BigInt): Option[ByteString] = + blockNumberMappingStorage.get(number) } object BlockchainReader { diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala index 3cabd8fdb5..3eb90f48c1 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala @@ -27,7 +27,7 @@ class BestBlockchainBranch( override def getBlockByNumber(number: BigInt): Option[Block] = if (tipBlockHeader.number <= number && number > 0) { for { - hash <- blockchainReader.getHashByBlockNumber(number) + hash <- getHashByBlockNumber(number) block <- blockchainReader.getBlockByHash(hash) } yield block } else None diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala index 7af015e834..c7785fe05c 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala @@ -36,7 +36,7 @@ class CheckpointingService( req.parentCheckpoint.forall(blockchainReader.getBlockHeaderByHash(_).exists(_.number < blockToReturnNum)) Task { - blockchainReader.getBlockByNumber(blockToReturnNum) + blockchainReader.getBestBranch.getBlockByNumber(blockToReturnNum) }.flatMap { case Some(b) if isValidParent => Task.now(Right(GetLatestBlockResponse(Some(BlockInfo(b.hash, b.number))))) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala index 5f7f3a1555..933602adbc 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala @@ -204,7 +204,7 @@ class EthProofService( private def resolveBlock(blockParam: BlockParam): Either[JsonRpcError, ResolvedBlock] = { def getBlock(number: BigInt): Either[JsonRpcError, Block] = - blockchainReader + blockchainReader.getBestBranch .getBlockByNumber(number) .toRight(JsonRpcError.InvalidParams(s"Block $number not found")) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala index 25307f6e82..164b76da52 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala @@ -157,7 +157,7 @@ class EthTxService( Task { val gasPrice = ((bestBlock - blockDifference) to bestBlock) - .flatMap(blockchainReader.getBlockByNumber) + .flatMap(blockchainReader.getBestBranch.getBlockByNumber) .flatMap(_.body.transactionList) .map(_.tx.gasPrice) if (gasPrice.nonEmpty) { diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala index 9733314e6f..a673f022a7 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala @@ -33,7 +33,7 @@ trait ResolveBlock { } private def getBlock(number: BigInt): Either[JsonRpcError, Block] = - blockchainReader + blockchainReader.getBestBranch .getBlockByNumber(number) .toRight(JsonRpcError.InvalidParams(s"Block $number not found")) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala index d055674d22..5d86866287 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala @@ -372,7 +372,7 @@ class TestService( val blockOpt = request.parameters.blockHashOrNumber .fold( - number => blockchainReader.getBlockByNumber(number), + number => blockchainReader.getBestBranch.getBlockByNumber(number), blockHash => blockchainReader.getBlockByHash(blockHash) ) @@ -411,7 +411,10 @@ class TestService( def storageRangeAt(request: StorageRangeRequest): ServiceResponse[StorageRangeResponse] = { val blockOpt = request.parameters.blockHashOrNumber - .fold(number => blockchainReader.getBlockByNumber(number), hash => blockchainReader.getBlockByHash(hash)) + .fold( + number => blockchainReader.getBestBranch.getBlockByNumber(number), + hash => blockchainReader.getBlockByHash(hash) + ) (for { block <- blockOpt.toRight(StorageRangeResponse(complete = false, Map.empty, None)) diff --git a/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala b/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala index 4cf44519ce..64ab33cfe5 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala @@ -305,7 +305,7 @@ class BlockImport( private def removeBlocksUntil(parent: ByteString, fromNumber: BigInt): List[BlockData] = { @tailrec def removeBlocksUntil(parent: ByteString, fromNumber: BigInt, acc: List[BlockData]): List[BlockData] = - blockchainReader.getBlockByNumber(fromNumber) match { + blockchainReader.getBestBranch.getBlockByNumber(fromNumber) match { case Some(block) if block.header.hash == parent || fromNumber == 0 => acc diff --git a/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala b/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala index 59f1e77842..c385a63daa 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala @@ -41,7 +41,8 @@ class BlockValidation( val remaining = n - queuedBlocks.length - 1 val numbers = (block.header.number - remaining) until block.header.number - val blocks = (numbers.toList.flatMap(blockchainReader.getBlockByNumber) :+ block) ::: queuedBlocks + val blocks = + (numbers.toList.flatMap(blockchainReader.getBestBranch.getBlockByNumber) :+ block) ::: queuedBlocks blocks } } diff --git a/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala b/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala index 30b8fc7b54..7308b0a067 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala @@ -74,7 +74,7 @@ class BranchResolution(blockchain: Blockchain, blockchainReader: BlockchainReade private def getTopBlocksFromNumber(from: BigInt): List[Block] = (from to blockchainReader.getBestBlockNumber()) - .flatMap(blockchainReader.getBlockByNumber) + .flatMap(blockchainReader.getBestBranch.getBlockByNumber) .toList } diff --git a/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala b/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala index d09f582e37..e475ae144a 100644 --- a/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala +++ b/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala @@ -75,7 +75,8 @@ class TestEthBlockServiceWrapper( .getBlockByNumber(request) .map( _.map { blockByBlockResponse => - val fullBlock = blockchainReader.getBlockByNumber(blockByBlockResponse.blockResponse.get.number).get + val fullBlock = + blockchainReader.getBestBranch.getBlockByNumber(blockByBlockResponse.blockResponse.get.number).get BlockByNumberResponse(blockByBlockResponse.blockResponse.map(response => toEthResponse(fullBlock, response))) } ) diff --git a/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala b/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala index 96999adafd..a76e929b9a 100644 --- a/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala +++ b/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala @@ -33,7 +33,7 @@ class TransactionHistoryService( val getLastCheckpoint = Task(blockchain.getLatestCheckpointBlockNumber()).memoizeOnSuccess val txnsFromBlocks = Observable .from(fromBlocks.reverse) - .mapParallelOrdered(10)(blockNr => Task(blockchainReader.getBlockByNumber(blockNr)))( + .mapParallelOrdered(10)(blockNr => Task(blockchainReader.getBestBranch.getBlockByNumber(blockNr)))( OverflowStrategy.Unbounded ) .collect { case Some(block) => block } From 5fb923724f1c1ac0bb6e5b597ad2d717d10f8afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Tue, 6 Jul 2021 14:05:28 +0200 Subject: [PATCH 3/9] fix unit tests --- .../ethereum/sync/RegularSyncItSpec.scala | 6 +++--- .../sync/util/RegularSyncItSpecUtils.scala | 2 ++ .../txExecTest/util/DumpChainApp.scala | 5 ++++- .../pow/validators/OmmersValidator.scala | 5 ++++- .../io/iohk/ethereum/domain/Blockchain.scala | 7 ++++--- .../ethereum/domain/BlockchainReader.scala | 19 ++++++++++++------- .../domain/branch/BestBlockchainBranch.scala | 2 +- .../jsonrpc/CheckpointingService.scala | 2 +- .../ethereum/jsonrpc/EthProofService.scala | 5 +++-- .../iohk/ethereum/jsonrpc/EthTxService.scala | 3 ++- .../iohk/ethereum/jsonrpc/ResolveBlock.scala | 5 +++-- .../iohk/ethereum/jsonrpc/TestService.scala | 4 ++-- .../io/iohk/ethereum/ledger/BlockImport.scala | 2 +- .../ethereum/ledger/BlockValidation.scala | 3 ++- .../ethereum/ledger/BranchResolution.scala | 6 ++++-- .../testmode/TestEthBlockServiceWrapper.scala | 4 ++-- .../TransactionHistoryService.scala | 2 +- .../validators/StdOmmersValidatorSpec.scala | 5 ++++- .../iohk/ethereum/domain/BlockchainSpec.scala | 9 ++++++--- .../jsonrpc/CheckpointingServiceSpec.scala | 15 +++++++++------ .../jsonrpc/EthBlocksServiceSpec.scala | 10 +++++++++- ...pcControllerEthLegacyTransactionSpec.scala | 5 +++++ .../jsonrpc/JsonRpcControllerEthSpec.scala | 4 ++++ .../ethereum/ledger/LedgerTestSetup.scala | 6 +++++- .../LegacyTransactionHistoryServiceSpec.scala | 1 + 25 files changed, 94 insertions(+), 43 deletions(-) diff --git a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala index e5a6870366..8c67455d4d 100644 --- a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala +++ b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala @@ -124,7 +124,7 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl _ <- peer2.importBlocksUntil(30)(IdentityUpdate) _ <- peer1.startRegularSync() _ <- peer2.startRegularSync() - _ <- peer2.addCheckpointedBlock(peer2.blockchainReader.getBlockByNumber(25).get) + _ <- peer2.addCheckpointedBlock(peer2.blockchainReader.getBestBranch().get.getBlockByNumber(25).get) _ <- peer2.waitForRegularSyncLoadLastBlock(length) _ <- peer1.connectToPeers(Set(peer2.node)) _ <- peer1.waitForRegularSyncLoadLastBlock(length) @@ -181,8 +181,8 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl ) ) ( - peer1.blockchainReader.getBlockByNumber(blockNumer + 1), - peer2.blockchainReader.getBlockByNumber(blockNumer + 1) + peer1.blockchainReader.getBestBranch().get.getBlockByNumber(blockNumer + 1), + peer2.blockchainReader.getBestBranch().get.getBlockByNumber(blockNumer + 1) ) match { case (Some(blockP1), Some(blockP2)) => assert(peer1.bl.getChainWeightByHash(blockP1.hash) == peer2.bl.getChainWeightByHash(blockP2.hash)) 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 137556fee7..1cdc4666bf 100644 --- a/src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala +++ b/src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala @@ -187,6 +187,8 @@ object RegularSyncItSpecUtils { Task(blockNumber match { case Some(bNumber) => blockchainReader + .getBestBranch() + .get .getBlockByNumber(bNumber) .getOrElse(throw new RuntimeException(s"block by number: $bNumber doesn't exist")) case None => blockchainReader.getBestBlock().get 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 0e98309cf8..024d01d32d 100644 --- a/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala +++ b/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala @@ -26,6 +26,7 @@ import io.iohk.ethereum.db.storage.pruning.PruningMode import io.iohk.ethereum.domain.BlockHeader.HeaderExtraFields.HefEmpty import io.iohk.ethereum.domain.Blockchain import io.iohk.ethereum.domain._ +import io.iohk.ethereum.domain.branch.BlockchainBranch import io.iohk.ethereum.jsonrpc.ProofService.EmptyStorageValueProof import io.iohk.ethereum.jsonrpc.ProofService.StorageProof import io.iohk.ethereum.jsonrpc.ProofService.StorageProofKey @@ -101,7 +102,9 @@ object DumpChainApp val blockchain: Blockchain = new BlockchainMock(genesisHash) val blockchainReader: BlockchainReader = mock[BlockchainReader] - (blockchainReader.getHashByBlockNumber _).expects(*).returning(Some(genesisHash)) + val bestChain: BlockchainBranch = mock[BlockchainBranch] + (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(Some(bestChain)) + (bestChain.getHashByBlockNumber _).expects(*).returning(Some(genesisHash)) val nodeStatus: NodeStatus = NodeStatus(key = nodeKey, serverStatus = ServerStatus.NotListening, discoveryStatus = ServerStatus.NotListening) diff --git a/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala b/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala index c9ad4b6383..238eb8790a 100644 --- a/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala +++ b/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala @@ -29,8 +29,11 @@ trait OmmersValidator { ): Either[OmmersError, OmmersValid] = { val getBlockHeaderByHash: ByteString => Option[BlockHeader] = blockchainReader.getBlockHeaderByHash + val bestBranch = blockchainReader.getBestBranch() val getNBlocksBack: (ByteString, Int) => List[Block] = - (_, n) => ((blockNumber - n) until blockNumber).toList.flatMap(blockchainReader.getBestBranch.getBlockByNumber) + (_, n) => + ((blockNumber - n) until blockNumber).toList + .flatMap(nb => bestBranch.flatMap(_.getBlockByNumber(nb))) validate(parentHash, blockNumber, ommers, getBlockHeaderByHash, getNBlocksBack) } diff --git a/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala b/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala index 2d3fb2d19b..f47da66d12 100644 --- a/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala +++ b/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala @@ -103,7 +103,8 @@ class BlockchainImpl( override def isInChain(hash: ByteString): Boolean = (for { header <- blockchainReader.getBlockHeaderByHash(hash) if header.number <= blockchainReader.getBestBlockNumber() - hash <- blockchainReader.getBestBranch().getHashByBlockNumber(header.number) + bestBranch <- blockchainReader.getBestBranch() + hash <- bestBranch.getHashByBlockNumber(header.number) } yield header.hash == hash).getOrElse(false) override def getChainWeightByHash(blockhash: ByteString): Option[ChainWeight] = chainWeightStorage.get(blockhash) @@ -223,7 +224,7 @@ class BlockchainImpl( val latestCheckpointNumber = getLatestCheckpointBlockNumber() val blockNumberMappingUpdates = - if (blockchainReader.getBestBranch().getHashByBlockNumber(block.number).contains(blockHash)) + if (blockchainReader.getBestBranch().flatMap(_.getHashByBlockNumber(block.number)).contains(blockHash)) removeBlockNumberMapping(block.number) else blockNumberMappingStorage.emptyBatchUpdate @@ -292,7 +293,7 @@ class BlockchainImpl( ): BigInt = if (blockNumberToCheck > 0) { val maybePreviousCheckpointBlockNumber = for { - currentBlock <- blockchainReader.getBestBranch.getBlockByNumber(blockNumberToCheck) + currentBlock <- blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(blockNumberToCheck)) if currentBlock.hasCheckpoint && currentBlock.number < latestCheckpointBlockNumber } yield currentBlock.number diff --git a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala index 0ff9f59ffa..d5af5804e3 100644 --- a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala +++ b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala @@ -69,12 +69,17 @@ class BlockchainReader( */ def getReceiptsByHash(blockhash: ByteString): Option[Seq[Receipt]] = receiptStorage.get(blockhash) - def getBestBranch(): BlockchainBranch = - new BestBlockchainBranch( - getBestBlock().map(_.header).getOrElse(genesisHeader), - blockNumberMappingStorage, - this - ) + /** get the current best stored branch */ + // FIXME this should not be an option as we should always have the genesis + // but some tests prevent it to simply be BlockchainBranch for now + def getBestBranch(): Option[BlockchainBranch] = + getBestBlock().map { block => + new BestBlockchainBranch( + block.header, + blockNumberMappingStorage, + this + ) + } def getBestBlockNumber(): BigInt = { val bestSavedBlockNumber = appStateStorage.getBestBlockNumber() @@ -105,7 +110,7 @@ class BlockchainReader( getBlockHeaderByNumber(0).get def genesisBlock: Block = - getBestBranch().getBlockByNumber(0).get + getBlockByNumber(0).get /** Allows to query for a block based on it's number * diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala index 3eb90f48c1..21cfdbbb5c 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala @@ -25,7 +25,7 @@ class BestBlockchainBranch( * */ override def getBlockByNumber(number: BigInt): Option[Block] = - if (tipBlockHeader.number <= number && number > 0) { + if (tipBlockHeader.number >= number && number >= 0) { for { hash <- getHashByBlockNumber(number) block <- blockchainReader.getBlockByHash(hash) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala index c7785fe05c..7b849bb6c1 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala @@ -36,7 +36,7 @@ class CheckpointingService( req.parentCheckpoint.forall(blockchainReader.getBlockHeaderByHash(_).exists(_.number < blockToReturnNum)) Task { - blockchainReader.getBestBranch.getBlockByNumber(blockToReturnNum) + blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(blockToReturnNum)) }.flatMap { case Some(b) if isValidParent => Task.now(Right(GetLatestBlockResponse(Some(BlockInfo(b.hash, b.number))))) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala index 933602adbc..9cde3fe16e 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala @@ -204,8 +204,9 @@ class EthProofService( private def resolveBlock(blockParam: BlockParam): Either[JsonRpcError, ResolvedBlock] = { def getBlock(number: BigInt): Either[JsonRpcError, Block] = - blockchainReader.getBestBranch - .getBlockByNumber(number) + blockchainReader + .getBestBranch() + .flatMap(_.getBlockByNumber(number)) .toRight(JsonRpcError.InvalidParams(s"Block $number not found")) def getLatestBlock(): Either[JsonRpcError, Block] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala index 164b76da52..9422ea2e23 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala @@ -156,8 +156,9 @@ class EthTxService( val bestBlock = blockchainReader.getBestBlockNumber() Task { + val bestBranch = blockchainReader.getBestBranch() val gasPrice = ((bestBlock - blockDifference) to bestBlock) - .flatMap(blockchainReader.getBestBranch.getBlockByNumber) + .flatMap(nb => bestBranch.flatMap(_.getBlockByNumber(nb))) .flatMap(_.body.transactionList) .map(_.tx.gasPrice) if (gasPrice.nonEmpty) { diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala index a673f022a7..f3591a4b36 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala @@ -33,8 +33,9 @@ trait ResolveBlock { } private def getBlock(number: BigInt): Either[JsonRpcError, Block] = - blockchainReader.getBestBranch - .getBlockByNumber(number) + blockchainReader + .getBestBranch() + .flatMap(_.getBlockByNumber(number)) .toRight(JsonRpcError.InvalidParams(s"Block $number not found")) private def getLatestBlock(): Either[JsonRpcError, Block] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala index 5d86866287..948a847233 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala @@ -372,7 +372,7 @@ class TestService( val blockOpt = request.parameters.blockHashOrNumber .fold( - number => blockchainReader.getBestBranch.getBlockByNumber(number), + number => blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(number)), blockHash => blockchainReader.getBlockByHash(blockHash) ) @@ -412,7 +412,7 @@ class TestService( val blockOpt = request.parameters.blockHashOrNumber .fold( - number => blockchainReader.getBestBranch.getBlockByNumber(number), + number => blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(number)), hash => blockchainReader.getBlockByHash(hash) ) diff --git a/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala b/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala index 64ab33cfe5..1398d94c7d 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala @@ -305,7 +305,7 @@ class BlockImport( private def removeBlocksUntil(parent: ByteString, fromNumber: BigInt): List[BlockData] = { @tailrec def removeBlocksUntil(parent: ByteString, fromNumber: BigInt, acc: List[BlockData]): List[BlockData] = - blockchainReader.getBestBranch.getBlockByNumber(fromNumber) match { + blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(fromNumber)) match { case Some(block) if block.header.hash == parent || fromNumber == 0 => acc diff --git a/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala b/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala index c385a63daa..c740cee8fa 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala @@ -41,8 +41,9 @@ class BlockValidation( val remaining = n - queuedBlocks.length - 1 val numbers = (block.header.number - remaining) until block.header.number + val bestBranch = blockchainReader.getBestBranch() val blocks = - (numbers.toList.flatMap(blockchainReader.getBestBranch.getBlockByNumber) :+ block) ::: queuedBlocks + (numbers.toList.flatMap(nb => bestBranch.flatMap(_.getBlockByNumber(nb))) :+ block) ::: queuedBlocks blocks } } diff --git a/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala b/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala index 7308b0a067..6c81c19421 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala @@ -72,10 +72,12 @@ class BranchResolution(blockchain: Blockchain, blockchainReader: BlockchainReade } } - private def getTopBlocksFromNumber(from: BigInt): List[Block] = + private def getTopBlocksFromNumber(from: BigInt): List[Block] = { + val bestBranch = blockchainReader.getBestBranch() (from to blockchainReader.getBestBlockNumber()) - .flatMap(blockchainReader.getBestBranch.getBlockByNumber) + .flatMap(nb => bestBranch.flatMap(_.getBlockByNumber(nb))) .toList + } } sealed trait BranchResolutionResult diff --git a/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala b/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala index e475ae144a..68f68d41e8 100644 --- a/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala +++ b/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala @@ -75,8 +75,8 @@ class TestEthBlockServiceWrapper( .getBlockByNumber(request) .map( _.map { blockByBlockResponse => - val fullBlock = - blockchainReader.getBestBranch.getBlockByNumber(blockByBlockResponse.blockResponse.get.number).get + val bestBranch = blockchainReader.getBestBranch().get + val fullBlock = bestBranch.getBlockByNumber(blockByBlockResponse.blockResponse.get.number).get BlockByNumberResponse(blockByBlockResponse.blockResponse.map(response => toEthResponse(fullBlock, response))) } ) diff --git a/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala b/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala index a76e929b9a..2029b2d298 100644 --- a/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala +++ b/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala @@ -33,7 +33,7 @@ class TransactionHistoryService( val getLastCheckpoint = Task(blockchain.getLatestCheckpointBlockNumber()).memoizeOnSuccess val txnsFromBlocks = Observable .from(fromBlocks.reverse) - .mapParallelOrdered(10)(blockNr => Task(blockchainReader.getBestBranch.getBlockByNumber(blockNr)))( + .mapParallelOrdered(10)(blockNr => Task(blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(blockNr))))( OverflowStrategy.Unbounded ) .collect { case Some(block) => block } diff --git a/src/test/scala/io/iohk/ethereum/consensus/pow/validators/StdOmmersValidatorSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/pow/validators/StdOmmersValidatorSpec.scala index 98400a469c..c8be13ba4b 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/pow/validators/StdOmmersValidatorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/pow/validators/StdOmmersValidatorSpec.scala @@ -79,7 +79,9 @@ class StdOmmersValidatorSpec extends AnyFlatSpec with Matchers with ScalaCheckPr it should "report failure if there is an ommer which that is not parent of an ancestor" in new BlockUtils { val getNBlocksBack: (ByteString, Int) => List[Block] = - (_, n) => ((ommersBlockNumber - n) until ommersBlockNumber).toList.flatMap(blockchainReader.getBlockByNumber) + (_, n) => + ((ommersBlockNumber - n) until ommersBlockNumber).toList + .flatMap(nb => blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(nb))) ommersValidator.validateOmmersAncestors( ommersBlockParentHash, @@ -462,6 +464,7 @@ class StdOmmersValidatorSpec extends AnyFlatSpec with Matchers with ScalaCheckPr .and(blockchainWriter.storeBlock(block95)) .and(blockchainWriter.storeBlock(block96)) .commit() + blockchain.saveBestKnownBlocks(block96.number) } } diff --git a/src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala b/src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala index e27ce0dee9..64268c851b 100644 --- a/src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala +++ b/src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala @@ -44,7 +44,8 @@ class BlockchainSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyCh it should "be able to store a block and retrieve it by number" in new EphemBlockchainTestSetup { val validBlock = Fixtures.Blocks.ValidBlock.block blockchainWriter.storeBlock(validBlock).commit() - val block = blockchainReader.getBlockByNumber(validBlock.header.number) + blockchain.saveBestKnownBlocks(validBlock.number) + val block = blockchainReader.getBestBranch().get.getBlockByNumber(validBlock.header.number) block.isDefined should ===(true) validBlock should ===(block.get) } @@ -67,8 +68,10 @@ class BlockchainSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyCh } it should "not return a value if not stored" in new EphemBlockchainTestSetup { - blockchainReader.getBlockByNumber(Fixtures.Blocks.ValidBlock.header.number).isEmpty should ===(true) - blockchainReader.getBlockByHash(Fixtures.Blocks.ValidBlock.header.hash).isEmpty should ===(true) + blockchainReader + .getBestBranch() + .flatMap(_.getBlockByNumber(Fixtures.Blocks.ValidBlock.header.number)) shouldBe None + blockchainReader.getBlockByHash(Fixtures.Blocks.ValidBlock.header.hash) shouldBe None } it should "be able to store a block with checkpoint and retrieve it and checkpoint" in new EphemBlockchainTestSetup { diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala index 64c69add45..11a3e76080 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala @@ -23,6 +23,7 @@ import io.iohk.ethereum.domain.BlockBody import io.iohk.ethereum.domain.BlockchainImpl import io.iohk.ethereum.domain.BlockchainReader import io.iohk.ethereum.domain.Checkpoint +import io.iohk.ethereum.domain.branch.BlockchainBranch import io.iohk.ethereum.jsonrpc.CheckpointingService._ import io.iohk.ethereum.ledger.BlockQueue @@ -53,7 +54,7 @@ class CheckpointingServiceSpec val expectedResponse = GetLatestBlockResponse(Some(BlockInfo(block.hash, block.number))) (blockchainReader.getBestBlockNumber _).expects().returning(bestBlockNum) - (blockchainReader.getBlockByNumber _).expects(checkpointedBlockNum).returning(Some(block)) + (bestChain.getBlockByNumber _).expects(checkpointedBlockNum).returning(Some(block)) val result = service.getLatestBlock(request) result.runSyncUnsafe() shouldEqual Right(expectedResponse) @@ -83,7 +84,7 @@ class CheckpointingServiceSpec (blockchainReader.getBlockHeaderByHash _) .expects(hash) .returning(Some(previousCheckpoint.header.copy(number = 0))) - (blockchainReader.getBlockByNumber _).expects(checkpointedBlockNum).returning(Some(block)) + (bestChain.getBlockByNumber _).expects(checkpointedBlockNum).returning(Some(block)) val result = service.getLatestBlock(request) result.runSyncUnsafe() shouldEqual Right(expectedResponse) @@ -111,7 +112,7 @@ class CheckpointingServiceSpec (blockchainReader.getBlockHeaderByHash _) .expects(hash) .returning(Some(previousCheckpoint.header.copy(number = bestBlockNum))) - (blockchainReader.getBlockByNumber _).expects(*).returning(Some(previousCheckpoint)) + (bestChain.getBlockByNumber _).expects(*).returning(Some(previousCheckpoint)) val result = service.getLatestBlock(request) result.runSyncUnsafe() shouldEqual Right(expectedResponse) @@ -139,7 +140,7 @@ class CheckpointingServiceSpec (blockchainReader.getBestBlockNumber _).expects().returning(bestBlockNum) (blockchainReader.getBlockHeaderByHash _).expects(hash).returning(None) - (blockchainReader.getBlockByNumber _).expects(checkpointedBlockNum).returning(Some(block)) + (bestChain.getBlockByNumber _).expects(checkpointedBlockNum).returning(Some(block)) val result = service.getLatestBlock(request) result.runSyncUnsafe() shouldEqual Right(expectedResponse) @@ -167,13 +168,13 @@ class CheckpointingServiceSpec (blockchainReader.getBestBlockNumber _) .expects() .returning(7) - (blockchainReader.getBlockByNumber _) + (bestChain.getBlockByNumber _) .expects(BigInt(4)) .returning(None) (blockchainReader.getBestBlockNumber _) .expects() .returning(7) - (blockchainReader.getBlockByNumber _) + (bestChain.getBlockByNumber _) .expects(BigInt(4)) .returning(Some(block)) @@ -185,6 +186,8 @@ class CheckpointingServiceSpec trait TestSetup { val blockchain: BlockchainImpl = mock[BlockchainImpl] val blockchainReader: BlockchainReader = mock[BlockchainReader] + val bestChain: BlockchainBranch = mock[BlockchainBranch] + (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(Some(bestChain)) val blockQueue: BlockQueue = mock[BlockQueue] val syncController: TestProbe = TestProbe() val checkpointBlockGenerator: CheckpointBlockGenerator = new CheckpointBlockGenerator() diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/EthBlocksServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/EthBlocksServiceSpec.scala index c7bf28b03b..38a875738c 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/EthBlocksServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/EthBlocksServiceSpec.scala @@ -173,6 +173,7 @@ class EthBlocksServiceSpec .storeBlock(blockToRequest) .and(blockchainWriter.storeChainWeight(blockToRequestHash, blockWeight)) .commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) val response = ethBlocksService.getBlockByNumber(request).runSyncUnsafe(Duration.Inf).toOption.get @@ -190,6 +191,7 @@ class EthBlocksServiceSpec it should "answer eth_getBlockByNumber with the block response correctly when it's chain weight is not in blockchain" in new TestSetup { blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) val response = ethBlocksService.getBlockByNumber(request).runSyncUnsafe(Duration.Inf).toOption.get @@ -208,6 +210,7 @@ class EthBlocksServiceSpec .storeBlock(blockToRequest) .and(blockchainWriter.storeChainWeight(blockToRequestHash, blockWeight)) .commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val request = BlockByNumberRequest(BlockParam.WithNumber(blockToRequestNumber), fullTxs = true) val response = @@ -222,6 +225,7 @@ class EthBlocksServiceSpec it should "get transaction count by block number" in new TestSetup { blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val response = ethBlocksService.getBlockTransactionCountByNumber( GetBlockTransactionCountByNumberRequest(BlockParam.WithNumber(blockToRequest.header.number)) @@ -253,6 +257,7 @@ class EthBlocksServiceSpec it should "answer eth_getUncleByBlockHashAndIndex with None when there's no uncle" in new TestSetup { blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) @@ -263,6 +268,7 @@ class EthBlocksServiceSpec it should "answer eth_getUncleByBlockHashAndIndex with None when there's no uncle in the requested index" in new TestSetup { blockchainWriter.storeBlock(blockToRequestWithUncles).commit() + blockchain.saveBestKnownBlocks(blockToRequestWithUncles.number) val uncleIndexToRequest = 0 val request = UncleByBlockHashAndIndexRequest(blockToRequestHash, uncleIndexToRequest) @@ -355,6 +361,7 @@ class EthBlocksServiceSpec it should "answer eth_getUncleByBlockNumberAndIndex correctly when the requested index has one but there's no chain weight for it" in new TestSetup { blockchainWriter.storeBlock(blockToRequestWithUncles).commit() + blockchain.saveBestKnownBlocks(blockToRequestWithUncles.number) val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) @@ -366,11 +373,12 @@ class EthBlocksServiceSpec response.uncleBlockResponse.get.uncles shouldBe Nil } - it should "anwer eth_getUncleByBlockNumberAndIndex correctly when the requested index has one and there's chain weight for it" in new TestSetup { + it should "answer eth_getUncleByBlockNumberAndIndex correctly when the requested index has one and there's chain weight for it" in new TestSetup { blockchainWriter .storeBlock(blockToRequestWithUncles) .and(blockchainWriter.storeChainWeight(uncle.hash, uncleWeight)) .commit() + blockchain.saveBestKnownBlocks(blockToRequestWithUncles.number) val uncleIndexToRequest = 0 val request = UncleByBlockNumberAndIndexRequest(BlockParam.WithNumber(blockToRequestNumber), uncleIndexToRequest) diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthLegacyTransactionSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthLegacyTransactionSpec.scala index 99528e1729..038fc2a698 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthLegacyTransactionSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthLegacyTransactionSpec.scala @@ -153,6 +153,7 @@ class JsonRpcControllerEthLegacyTransactionSpec val txIndex = 1 blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getTransactionByBlockNumberAndIndex", @@ -175,6 +176,7 @@ class JsonRpcControllerEthLegacyTransactionSpec val txIndex = 1 blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.header.number) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getTransactionByBlockNumberAndIndex", @@ -224,6 +226,7 @@ class JsonRpcControllerEthLegacyTransactionSpec val txIndex = 1 blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.header.number) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getRawTransactionByBlockNumberAndIndex", @@ -247,6 +250,7 @@ class JsonRpcControllerEthLegacyTransactionSpec val txIndex = 1 blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.header.number) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getRawTransactionByBlockNumberAndIndex", @@ -324,6 +328,7 @@ class JsonRpcControllerEthLegacyTransactionSpec val blockToRequest = Block(Fixtures.Blocks.Block3125369.header, Fixtures.Blocks.Block3125369.body) blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.header.number) val rpcRequest = newJsonRpcRequest( "eth_getBlockTransactionCountByHash", diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala index 5c5adbb193..32ad88b4a4 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/JsonRpcControllerEthSpec.scala @@ -167,6 +167,7 @@ class JsonRpcControllerEthSpec .storeBlock(blockToRequest) .and(blockchainWriter.storeChainWeight(blockToRequest.header.hash, blockWeight)) .commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val request = newJsonRpcRequest( "eth_getBlockByNumber", @@ -188,6 +189,7 @@ class JsonRpcControllerEthSpec .storeBlock(blockToRequest) .and(blockchainWriter.storeChainWeight(blockToRequest.header.hash, blockWeight)) .commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val request = newJsonRpcRequest( "eth_getBlockByNumber", @@ -209,6 +211,7 @@ class JsonRpcControllerEthSpec .storeBlock(blockToRequest) .and(blockchainWriter.storeChainWeight(blockToRequest.header.hash, blockWeight)) .commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val request = newJsonRpcRequest( "eth_getBlockByNumber", @@ -252,6 +255,7 @@ class JsonRpcControllerEthSpec val blockToRequest = Block(Fixtures.Blocks.Block3125369.header, BlockBody(Nil, Seq(uncle))) blockchainWriter.storeBlock(blockToRequest).commit() + blockchain.saveBestKnownBlocks(blockToRequest.number) val request: JsonRpcRequest = newJsonRpcRequest( "eth_getUncleByBlockNumberAndIndex", diff --git a/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala b/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala index e86a907511..0703e68a99 100644 --- a/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala +++ b/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala @@ -32,6 +32,7 @@ import io.iohk.ethereum.consensus.validators.BlockHeaderValidator import io.iohk.ethereum.crypto.generateKeyPair import io.iohk.ethereum.crypto.kec256 import io.iohk.ethereum.domain._ +import io.iohk.ethereum.domain.branch.BlockchainBranch import io.iohk.ethereum.ledger.BlockExecutionError.ValidationAfterExecError import io.iohk.ethereum.ledger.PC import io.iohk.ethereum.ledger.PR @@ -410,8 +411,11 @@ trait TestSetupWithVmAndValidators extends EphemBlockchainTestSetup { trait MockBlockchain extends MockFactory { self: TestSetupWithVmAndValidators => //+ cake overrides + + val bestChain: BlockchainBranch = mock[BlockchainBranch] override lazy val blockchainReader: BlockchainReader = mock[BlockchainReader] override lazy val blockchainWriter: BlockchainWriter = mock[BlockchainWriter] + (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(Some(bestChain)) override lazy val blockchain: BlockchainImpl = mock[BlockchainImpl] //- cake overrides @@ -455,7 +459,7 @@ trait MockBlockchain extends MockFactory { self: TestSetupWithVmAndValidators => (blockchain.isInChain _).expects(hash).returning(result) def setBlockByNumber(number: BigInt, block: Option[Block]): CallHandler1[BigInt, Option[Block]] = - (blockchainReader.getBlockByNumber _).expects(number).returning(block) + (bestChain.getBlockByNumber _).expects(number).returning(block) def setGenesisHeader(header: BlockHeader): Unit = (() => blockchainReader.genesisHeader).expects().returning(header) diff --git a/src/test/scala/io/iohk/ethereum/transactions/LegacyTransactionHistoryServiceSpec.scala b/src/test/scala/io/iohk/ethereum/transactions/LegacyTransactionHistoryServiceSpec.scala index b073de9d6a..73068ad27e 100644 --- a/src/test/scala/io/iohk/ethereum/transactions/LegacyTransactionHistoryServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/transactions/LegacyTransactionHistoryServiceSpec.scala @@ -87,6 +87,7 @@ class LegacyTransactionHistoryServiceSpec .and(blockchainWriter.storeBlock(blockWithTxs2and3)) .and(blockchainWriter.storeReceipts(blockWithTxs2and3.hash, blockTx2And3Receipts)) .commit() + blockchain.saveBestKnownBlocks(blockWithTxs2and3.number) } response <- transactionHistoryService.getAccountTransactions(address, BigInt(3125360) to BigInt(3125370)) } yield assert(response === expectedTxs) From 8280cc7ab5f22131a494e93696439e1d4a7b09e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Wed, 7 Jul 2021 15:37:56 +0200 Subject: [PATCH 4/9] remove irrelevant comment --- .../iohk/ethereum/domain/branch/BestBlockchainBranch.scala | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala index 21cfdbbb5c..0572db4746 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala @@ -17,12 +17,9 @@ class BestBlockchainBranch( ) extends BlockchainBranch { /* The following assumptions are made in this class : - * - the whole branch exist in storage + * - The whole branch exist in storage * - The various metadata and index are consistent - * - * If those assumptions are found to be false, then the application is in an inconsistent - * state and the class will throw. - * */ + */ override def getBlockByNumber(number: BigInt): Option[Block] = if (tipBlockHeader.number >= number && number >= 0) { From a9065d9dacd00da1f92d6689897f0c9acd07d505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Fri, 9 Jul 2021 11:09:24 +0200 Subject: [PATCH 5/9] Create EmptyBlochainBranch and make getBestChain return it if there no known best block --- .../ethereum/sync/RegularSyncItSpec.scala | 6 +++--- .../sync/util/RegularSyncItSpecUtils.scala | 1 - .../txExecTest/util/DumpChainApp.scala | 2 +- .../pow/validators/OmmersValidator.scala | 2 +- .../io/iohk/ethereum/domain/Blockchain.scala | 7 +++---- .../ethereum/domain/BlockchainReader.scala | 21 ++++++++++--------- .../domain/branch/EmptyBlockchainBranch.scala | 11 ++++++++++ .../jsonrpc/CheckpointingService.scala | 2 +- .../ethereum/jsonrpc/EthProofService.scala | 2 +- .../iohk/ethereum/jsonrpc/EthTxService.scala | 2 +- .../iohk/ethereum/jsonrpc/ResolveBlock.scala | 2 +- .../iohk/ethereum/jsonrpc/TestService.scala | 4 ++-- .../io/iohk/ethereum/ledger/BlockImport.scala | 2 +- .../ethereum/ledger/BlockValidation.scala | 2 +- .../ethereum/ledger/BranchResolution.scala | 2 +- .../testmode/TestEthBlockServiceWrapper.scala | 2 +- .../TransactionHistoryService.scala | 2 +- .../validators/StdOmmersValidatorSpec.scala | 2 +- .../iohk/ethereum/domain/BlockchainSpec.scala | 4 ++-- .../jsonrpc/CheckpointingServiceSpec.scala | 2 +- .../ethereum/ledger/LedgerTestSetup.scala | 2 +- 21 files changed, 46 insertions(+), 36 deletions(-) create mode 100644 src/main/scala/io/iohk/ethereum/domain/branch/EmptyBlockchainBranch.scala diff --git a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala index 8c67455d4d..c29838ad23 100644 --- a/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala +++ b/src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala @@ -124,7 +124,7 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl _ <- peer2.importBlocksUntil(30)(IdentityUpdate) _ <- peer1.startRegularSync() _ <- peer2.startRegularSync() - _ <- peer2.addCheckpointedBlock(peer2.blockchainReader.getBestBranch().get.getBlockByNumber(25).get) + _ <- peer2.addCheckpointedBlock(peer2.blockchainReader.getBestBranch().getBlockByNumber(25).get) _ <- peer2.waitForRegularSyncLoadLastBlock(length) _ <- peer1.connectToPeers(Set(peer2.node)) _ <- peer1.waitForRegularSyncLoadLastBlock(length) @@ -181,8 +181,8 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl ) ) ( - peer1.blockchainReader.getBestBranch().get.getBlockByNumber(blockNumer + 1), - peer2.blockchainReader.getBestBranch().get.getBlockByNumber(blockNumer + 1) + peer1.blockchainReader.getBestBranch().getBlockByNumber(blockNumer + 1), + peer2.blockchainReader.getBestBranch().getBlockByNumber(blockNumer + 1) ) match { case (Some(blockP1), Some(blockP2)) => assert(peer1.bl.getChainWeightByHash(blockP1.hash) == peer2.bl.getChainWeightByHash(blockP2.hash)) 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 1cdc4666bf..6e6019791c 100644 --- a/src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala +++ b/src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala @@ -188,7 +188,6 @@ object RegularSyncItSpecUtils { case Some(bNumber) => blockchainReader .getBestBranch() - .get .getBlockByNumber(bNumber) .getOrElse(throw new RuntimeException(s"block by number: $bNumber doesn't exist")) case None => blockchainReader.getBestBlock().get 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 024d01d32d..4f3e7c07db 100644 --- a/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala +++ b/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala @@ -103,7 +103,7 @@ object DumpChainApp val blockchain: Blockchain = new BlockchainMock(genesisHash) val blockchainReader: BlockchainReader = mock[BlockchainReader] val bestChain: BlockchainBranch = mock[BlockchainBranch] - (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(Some(bestChain)) + (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(bestChain) (bestChain.getHashByBlockNumber _).expects(*).returning(Some(genesisHash)) val nodeStatus: NodeStatus = diff --git a/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala b/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala index 238eb8790a..1e4408921b 100644 --- a/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala +++ b/src/main/scala/io/iohk/ethereum/consensus/pow/validators/OmmersValidator.scala @@ -33,7 +33,7 @@ trait OmmersValidator { val getNBlocksBack: (ByteString, Int) => List[Block] = (_, n) => ((blockNumber - n) until blockNumber).toList - .flatMap(nb => bestBranch.flatMap(_.getBlockByNumber(nb))) + .flatMap(nb => bestBranch.getBlockByNumber(nb)) validate(parentHash, blockNumber, ommers, getBlockHeaderByHash, getNBlocksBack) } diff --git a/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala b/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala index f47da66d12..81cbe4f255 100644 --- a/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala +++ b/src/main/scala/io/iohk/ethereum/domain/Blockchain.scala @@ -103,8 +103,7 @@ class BlockchainImpl( override def isInChain(hash: ByteString): Boolean = (for { header <- blockchainReader.getBlockHeaderByHash(hash) if header.number <= blockchainReader.getBestBlockNumber() - bestBranch <- blockchainReader.getBestBranch() - hash <- bestBranch.getHashByBlockNumber(header.number) + hash <- blockchainReader.getBestBranch().getHashByBlockNumber(header.number) } yield header.hash == hash).getOrElse(false) override def getChainWeightByHash(blockhash: ByteString): Option[ChainWeight] = chainWeightStorage.get(blockhash) @@ -224,7 +223,7 @@ class BlockchainImpl( val latestCheckpointNumber = getLatestCheckpointBlockNumber() val blockNumberMappingUpdates = - if (blockchainReader.getBestBranch().flatMap(_.getHashByBlockNumber(block.number)).contains(blockHash)) + if (blockchainReader.getBestBranch().getHashByBlockNumber(block.number).contains(blockHash)) removeBlockNumberMapping(block.number) else blockNumberMappingStorage.emptyBatchUpdate @@ -293,7 +292,7 @@ class BlockchainImpl( ): BigInt = if (blockNumberToCheck > 0) { val maybePreviousCheckpointBlockNumber = for { - currentBlock <- blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(blockNumberToCheck)) + currentBlock <- blockchainReader.getBestBranch().getBlockByNumber(blockNumberToCheck) if currentBlock.hasCheckpoint && currentBlock.number < latestCheckpointBlockNumber } yield currentBlock.number diff --git a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala index d5af5804e3..98f3698495 100644 --- a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala +++ b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala @@ -10,6 +10,7 @@ import io.iohk.ethereum.db.storage.ReceiptStorage import io.iohk.ethereum.db.storage.StateStorage import io.iohk.ethereum.domain.branch.BestBlockchainBranch import io.iohk.ethereum.domain.branch.BlockchainBranch +import io.iohk.ethereum.domain.branch.EmptyBlockchainBranch import io.iohk.ethereum.mpt.MptNode import io.iohk.ethereum.utils.Logger @@ -70,16 +71,16 @@ class BlockchainReader( def getReceiptsByHash(blockhash: ByteString): Option[Seq[Receipt]] = receiptStorage.get(blockhash) /** get the current best stored branch */ - // FIXME this should not be an option as we should always have the genesis - // but some tests prevent it to simply be BlockchainBranch for now - def getBestBranch(): Option[BlockchainBranch] = - getBestBlock().map { block => - new BestBlockchainBranch( - block.header, - blockNumberMappingStorage, - this - ) - } + def getBestBranch(): BlockchainBranch = + getBestBlock() + .map { block => + new BestBlockchainBranch( + block.header, + blockNumberMappingStorage, + this + ) + } + .getOrElse(EmptyBlockchainBranch) def getBestBlockNumber(): BigInt = { val bestSavedBlockNumber = appStateStorage.getBestBlockNumber() diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/EmptyBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/EmptyBlockchainBranch.scala new file mode 100644 index 0000000000..950c2244cd --- /dev/null +++ b/src/main/scala/io/iohk/ethereum/domain/branch/EmptyBlockchainBranch.scala @@ -0,0 +1,11 @@ +package io.iohk.ethereum.domain.branch +import akka.util.ByteString + +import io.iohk.ethereum.domain.Block + +object EmptyBlockchainBranch extends BlockchainBranch { + + override def getBlockByNumber(number: BigInt): Option[Block] = None + + override def getHashByBlockNumber(number: BigInt): Option[ByteString] = None +} diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala index 7b849bb6c1..d76fa40550 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/CheckpointingService.scala @@ -36,7 +36,7 @@ class CheckpointingService( req.parentCheckpoint.forall(blockchainReader.getBlockHeaderByHash(_).exists(_.number < blockToReturnNum)) Task { - blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(blockToReturnNum)) + blockchainReader.getBestBranch().getBlockByNumber(blockToReturnNum) }.flatMap { case Some(b) if isValidParent => Task.now(Right(GetLatestBlockResponse(Some(BlockInfo(b.hash, b.number))))) diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala index 9cde3fe16e..a020450b54 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthProofService.scala @@ -206,7 +206,7 @@ class EthProofService( def getBlock(number: BigInt): Either[JsonRpcError, Block] = blockchainReader .getBestBranch() - .flatMap(_.getBlockByNumber(number)) + .getBlockByNumber(number) .toRight(JsonRpcError.InvalidParams(s"Block $number not found")) def getLatestBlock(): Either[JsonRpcError, Block] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala index 9422ea2e23..7f63c4f5ff 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/EthTxService.scala @@ -158,7 +158,7 @@ class EthTxService( Task { val bestBranch = blockchainReader.getBestBranch() val gasPrice = ((bestBlock - blockDifference) to bestBlock) - .flatMap(nb => bestBranch.flatMap(_.getBlockByNumber(nb))) + .flatMap(nb => bestBranch.getBlockByNumber(nb)) .flatMap(_.body.transactionList) .map(_.tx.gasPrice) if (gasPrice.nonEmpty) { diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala index f3591a4b36..d89476ac23 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/ResolveBlock.scala @@ -35,7 +35,7 @@ trait ResolveBlock { private def getBlock(number: BigInt): Either[JsonRpcError, Block] = blockchainReader .getBestBranch() - .flatMap(_.getBlockByNumber(number)) + .getBlockByNumber(number) .toRight(JsonRpcError.InvalidParams(s"Block $number not found")) private def getLatestBlock(): Either[JsonRpcError, Block] = diff --git a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala index 948a847233..498559b73e 100644 --- a/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala +++ b/src/main/scala/io/iohk/ethereum/jsonrpc/TestService.scala @@ -372,7 +372,7 @@ class TestService( val blockOpt = request.parameters.blockHashOrNumber .fold( - number => blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(number)), + number => blockchainReader.getBestBranch().getBlockByNumber(number), blockHash => blockchainReader.getBlockByHash(blockHash) ) @@ -412,7 +412,7 @@ class TestService( val blockOpt = request.parameters.blockHashOrNumber .fold( - number => blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(number)), + number => blockchainReader.getBestBranch().getBlockByNumber(number), hash => blockchainReader.getBlockByHash(hash) ) diff --git a/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala b/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala index 1398d94c7d..c92af763cd 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BlockImport.scala @@ -305,7 +305,7 @@ class BlockImport( private def removeBlocksUntil(parent: ByteString, fromNumber: BigInt): List[BlockData] = { @tailrec def removeBlocksUntil(parent: ByteString, fromNumber: BigInt, acc: List[BlockData]): List[BlockData] = - blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(fromNumber)) match { + blockchainReader.getBestBranch().getBlockByNumber(fromNumber) match { case Some(block) if block.header.hash == parent || fromNumber == 0 => acc diff --git a/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala b/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala index c740cee8fa..9d315c6209 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BlockValidation.scala @@ -43,7 +43,7 @@ class BlockValidation( val numbers = (block.header.number - remaining) until block.header.number val bestBranch = blockchainReader.getBestBranch() val blocks = - (numbers.toList.flatMap(nb => bestBranch.flatMap(_.getBlockByNumber(nb))) :+ block) ::: queuedBlocks + (numbers.toList.flatMap(nb => bestBranch.getBlockByNumber(nb)) :+ block) ::: queuedBlocks blocks } } diff --git a/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala b/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala index 6c81c19421..9e2ecc42f4 100644 --- a/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala +++ b/src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala @@ -75,7 +75,7 @@ class BranchResolution(blockchain: Blockchain, blockchainReader: BlockchainReade private def getTopBlocksFromNumber(from: BigInt): List[Block] = { val bestBranch = blockchainReader.getBestBranch() (from to blockchainReader.getBestBlockNumber()) - .flatMap(nb => bestBranch.flatMap(_.getBlockByNumber(nb))) + .flatMap(nb => bestBranch.getBlockByNumber(nb)) .toList } } diff --git a/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala b/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala index 68f68d41e8..f481a5cf85 100644 --- a/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala +++ b/src/main/scala/io/iohk/ethereum/testmode/TestEthBlockServiceWrapper.scala @@ -75,7 +75,7 @@ class TestEthBlockServiceWrapper( .getBlockByNumber(request) .map( _.map { blockByBlockResponse => - val bestBranch = blockchainReader.getBestBranch().get + val bestBranch = blockchainReader.getBestBranch() val fullBlock = bestBranch.getBlockByNumber(blockByBlockResponse.blockResponse.get.number).get BlockByNumberResponse(blockByBlockResponse.blockResponse.map(response => toEthResponse(fullBlock, response))) } diff --git a/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala b/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala index 2029b2d298..753a6b1ca0 100644 --- a/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala +++ b/src/main/scala/io/iohk/ethereum/transactions/TransactionHistoryService.scala @@ -33,7 +33,7 @@ class TransactionHistoryService( val getLastCheckpoint = Task(blockchain.getLatestCheckpointBlockNumber()).memoizeOnSuccess val txnsFromBlocks = Observable .from(fromBlocks.reverse) - .mapParallelOrdered(10)(blockNr => Task(blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(blockNr))))( + .mapParallelOrdered(10)(blockNr => Task(blockchainReader.getBestBranch().getBlockByNumber(blockNr)))( OverflowStrategy.Unbounded ) .collect { case Some(block) => block } diff --git a/src/test/scala/io/iohk/ethereum/consensus/pow/validators/StdOmmersValidatorSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/pow/validators/StdOmmersValidatorSpec.scala index c8be13ba4b..6bba890559 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/pow/validators/StdOmmersValidatorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/pow/validators/StdOmmersValidatorSpec.scala @@ -81,7 +81,7 @@ class StdOmmersValidatorSpec extends AnyFlatSpec with Matchers with ScalaCheckPr val getNBlocksBack: (ByteString, Int) => List[Block] = (_, n) => ((ommersBlockNumber - n) until ommersBlockNumber).toList - .flatMap(nb => blockchainReader.getBestBranch().flatMap(_.getBlockByNumber(nb))) + .flatMap(nb => blockchainReader.getBestBranch().getBlockByNumber(nb)) ommersValidator.validateOmmersAncestors( ommersBlockParentHash, diff --git a/src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala b/src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala index 64268c851b..d1cdd062cf 100644 --- a/src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala +++ b/src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala @@ -45,7 +45,7 @@ class BlockchainSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyCh val validBlock = Fixtures.Blocks.ValidBlock.block blockchainWriter.storeBlock(validBlock).commit() blockchain.saveBestKnownBlocks(validBlock.number) - val block = blockchainReader.getBestBranch().get.getBlockByNumber(validBlock.header.number) + val block = blockchainReader.getBestBranch().getBlockByNumber(validBlock.header.number) block.isDefined should ===(true) validBlock should ===(block.get) } @@ -70,7 +70,7 @@ class BlockchainSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyCh it should "not return a value if not stored" in new EphemBlockchainTestSetup { blockchainReader .getBestBranch() - .flatMap(_.getBlockByNumber(Fixtures.Blocks.ValidBlock.header.number)) shouldBe None + .getBlockByNumber(Fixtures.Blocks.ValidBlock.header.number) shouldBe None blockchainReader.getBlockByHash(Fixtures.Blocks.ValidBlock.header.hash) shouldBe None } diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala index 11a3e76080..72309e870f 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala @@ -187,7 +187,7 @@ class CheckpointingServiceSpec val blockchain: BlockchainImpl = mock[BlockchainImpl] val blockchainReader: BlockchainReader = mock[BlockchainReader] val bestChain: BlockchainBranch = mock[BlockchainBranch] - (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(Some(bestChain)) + (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(bestChain) val blockQueue: BlockQueue = mock[BlockQueue] val syncController: TestProbe = TestProbe() val checkpointBlockGenerator: CheckpointBlockGenerator = new CheckpointBlockGenerator() diff --git a/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala b/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala index 0703e68a99..5f933fe801 100644 --- a/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala +++ b/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala @@ -415,7 +415,7 @@ trait MockBlockchain extends MockFactory { self: TestSetupWithVmAndValidators => val bestChain: BlockchainBranch = mock[BlockchainBranch] override lazy val blockchainReader: BlockchainReader = mock[BlockchainReader] override lazy val blockchainWriter: BlockchainWriter = mock[BlockchainWriter] - (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(Some(bestChain)) + (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(bestChain) override lazy val blockchain: BlockchainImpl = mock[BlockchainImpl] //- cake overrides From 7670d4d70f7a7f59154d873b1d166e81391ca09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Mon, 12 Jul 2021 08:44:59 +0200 Subject: [PATCH 6/9] check the number when using getHashByBlockNumber --- .../io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala index 0572db4746..ed72896452 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala @@ -30,5 +30,7 @@ class BestBlockchainBranch( } else None override def getHashByBlockNumber(number: BigInt): Option[ByteString] = - bestChainBlockNumberMappingStorage.get(number) + if (tipBlockHeader.number >= number && number >= 0) { + bestChainBlockNumberMappingStorage.get(number) + } else None } From 0bf5a41ad014cc086a937028d5ee9fb1f7fb0667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Tue, 13 Jul 2021 14:53:05 +0200 Subject: [PATCH 7/9] fix typo Co-authored-by: Anastasiia Pushkina --- .../io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala index ed72896452..2b5f01df50 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala @@ -17,7 +17,7 @@ class BestBlockchainBranch( ) extends BlockchainBranch { /* The following assumptions are made in this class : - * - The whole branch exist in storage + * - The whole branch exists in storage * - The various metadata and index are consistent */ From 98f66876d340b4e066e2be6537050f7457d3cb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Tue, 13 Jul 2021 14:59:21 +0200 Subject: [PATCH 8/9] Rephrase scaladoc comment and remove TODO --- .../iohk/ethereum/domain/branch/BestBlockchainBranch.scala | 5 ++--- .../io/iohk/ethereum/domain/branch/BlockchainBranch.scala | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala index 2b5f01df50..b685f3c0a0 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala @@ -6,9 +6,8 @@ import io.iohk.ethereum.domain.Block import io.iohk.ethereum.domain.BlockHeader import io.iohk.ethereum.domain.BlockchainReader -/** A Branch instance which only works for the best canonical branch. As this branch - * currently has specific indexes (particularly regarding accessing blocks by number), - * it will uses thoses to provide better performance. +/** A Branch instance which only works for the best canonical branch or a subset of this branch. + * This implementation uses the existing storage indexes to access blocks by number more efficiently. */ class BestBlockchainBranch( tipBlockHeader: BlockHeader, diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala index f647f4620e..b913466b43 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala @@ -4,7 +4,6 @@ import akka.util.ByteString import io.iohk.ethereum.domain.Block -// TODO choose a name : ChainInstance, BlockchainBranch, Branch, Blockchain ? trait BlockchainBranch { /** Returns a block inside this branch based on its number */ From 00cb79ebb1b0b24d0ecda5770b90b6f1617547b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Fri, 16 Jul 2021 09:03:28 +0200 Subject: [PATCH 9/9] rename BlockchainBranch to Branch --- .../iohk/ethereum/txExecTest/util/DumpChainApp.scala | 4 ++-- .../io/iohk/ethereum/domain/BlockchainReader.scala | 12 ++++++------ .../{BestBlockchainBranch.scala => BestBranch.scala} | 4 ++-- .../branch/{BlockchainBranch.scala => Branch.scala} | 3 ++- ...mptyBlockchainBranch.scala => EmptyBranch$.scala} | 2 +- .../ethereum/jsonrpc/CheckpointingServiceSpec.scala | 4 ++-- .../io/iohk/ethereum/ledger/LedgerTestSetup.scala | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) rename src/main/scala/io/iohk/ethereum/domain/branch/{BestBlockchainBranch.scala => BestBranch.scala} (95%) rename src/main/scala/io/iohk/ethereum/domain/branch/{BlockchainBranch.scala => Branch.scala} (84%) rename src/main/scala/io/iohk/ethereum/domain/branch/{EmptyBlockchainBranch.scala => EmptyBranch$.scala} (82%) 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 4f3e7c07db..40126b1709 100644 --- a/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala +++ b/src/it/scala/io/iohk/ethereum/txExecTest/util/DumpChainApp.scala @@ -26,7 +26,7 @@ import io.iohk.ethereum.db.storage.pruning.PruningMode import io.iohk.ethereum.domain.BlockHeader.HeaderExtraFields.HefEmpty import io.iohk.ethereum.domain.Blockchain import io.iohk.ethereum.domain._ -import io.iohk.ethereum.domain.branch.BlockchainBranch +import io.iohk.ethereum.domain.branch.Branch import io.iohk.ethereum.jsonrpc.ProofService.EmptyStorageValueProof import io.iohk.ethereum.jsonrpc.ProofService.StorageProof import io.iohk.ethereum.jsonrpc.ProofService.StorageProofKey @@ -102,7 +102,7 @@ object DumpChainApp val blockchain: Blockchain = new BlockchainMock(genesisHash) val blockchainReader: BlockchainReader = mock[BlockchainReader] - val bestChain: BlockchainBranch = mock[BlockchainBranch] + val bestChain: Branch = mock[Branch] (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(bestChain) (bestChain.getHashByBlockNumber _).expects(*).returning(Some(genesisHash)) diff --git a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala index 98f3698495..93e5468583 100644 --- a/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala +++ b/src/main/scala/io/iohk/ethereum/domain/BlockchainReader.scala @@ -8,9 +8,9 @@ import io.iohk.ethereum.db.storage.BlockHeadersStorage import io.iohk.ethereum.db.storage.BlockNumberMappingStorage import io.iohk.ethereum.db.storage.ReceiptStorage import io.iohk.ethereum.db.storage.StateStorage -import io.iohk.ethereum.domain.branch.BestBlockchainBranch -import io.iohk.ethereum.domain.branch.BlockchainBranch -import io.iohk.ethereum.domain.branch.EmptyBlockchainBranch +import io.iohk.ethereum.domain.branch.BestBranch +import io.iohk.ethereum.domain.branch.Branch +import io.iohk.ethereum.domain.branch.EmptyBranch$ import io.iohk.ethereum.mpt.MptNode import io.iohk.ethereum.utils.Logger @@ -71,16 +71,16 @@ class BlockchainReader( def getReceiptsByHash(blockhash: ByteString): Option[Seq[Receipt]] = receiptStorage.get(blockhash) /** get the current best stored branch */ - def getBestBranch(): BlockchainBranch = + def getBestBranch(): Branch = getBestBlock() .map { block => - new BestBlockchainBranch( + new BestBranch( block.header, blockNumberMappingStorage, this ) } - .getOrElse(EmptyBlockchainBranch) + .getOrElse(EmptyBranch$) def getBestBlockNumber(): BigInt = { val bestSavedBlockNumber = appStateStorage.getBestBlockNumber() diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/BestBranch.scala similarity index 95% rename from src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala rename to src/main/scala/io/iohk/ethereum/domain/branch/BestBranch.scala index b685f3c0a0..7c5aea1079 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BestBlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/BestBranch.scala @@ -9,11 +9,11 @@ import io.iohk.ethereum.domain.BlockchainReader /** A Branch instance which only works for the best canonical branch or a subset of this branch. * This implementation uses the existing storage indexes to access blocks by number more efficiently. */ -class BestBlockchainBranch( +class BestBranch( tipBlockHeader: BlockHeader, bestChainBlockNumberMappingStorage: BlockNumberMappingStorage, blockchainReader: BlockchainReader -) extends BlockchainBranch { +) extends Branch { /* The following assumptions are made in this class : * - The whole branch exists in storage diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/Branch.scala similarity index 84% rename from src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala rename to src/main/scala/io/iohk/ethereum/domain/branch/Branch.scala index b913466b43..118910b6e9 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/BlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/Branch.scala @@ -4,7 +4,8 @@ import akka.util.ByteString import io.iohk.ethereum.domain.Block -trait BlockchainBranch { +/** An interface to manipulate blockchain branches */ +trait Branch { /** Returns a block inside this branch based on its number */ def getBlockByNumber(number: BigInt): Option[Block] diff --git a/src/main/scala/io/iohk/ethereum/domain/branch/EmptyBlockchainBranch.scala b/src/main/scala/io/iohk/ethereum/domain/branch/EmptyBranch$.scala similarity index 82% rename from src/main/scala/io/iohk/ethereum/domain/branch/EmptyBlockchainBranch.scala rename to src/main/scala/io/iohk/ethereum/domain/branch/EmptyBranch$.scala index 950c2244cd..0f72afe21b 100644 --- a/src/main/scala/io/iohk/ethereum/domain/branch/EmptyBlockchainBranch.scala +++ b/src/main/scala/io/iohk/ethereum/domain/branch/EmptyBranch$.scala @@ -3,7 +3,7 @@ import akka.util.ByteString import io.iohk.ethereum.domain.Block -object EmptyBlockchainBranch extends BlockchainBranch { +object EmptyBranch$ extends Branch { override def getBlockByNumber(number: BigInt): Option[Block] = None diff --git a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala index 72309e870f..7ab0ef4c0c 100644 --- a/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala +++ b/src/test/scala/io/iohk/ethereum/jsonrpc/CheckpointingServiceSpec.scala @@ -23,7 +23,7 @@ import io.iohk.ethereum.domain.BlockBody import io.iohk.ethereum.domain.BlockchainImpl import io.iohk.ethereum.domain.BlockchainReader import io.iohk.ethereum.domain.Checkpoint -import io.iohk.ethereum.domain.branch.BlockchainBranch +import io.iohk.ethereum.domain.branch.Branch import io.iohk.ethereum.jsonrpc.CheckpointingService._ import io.iohk.ethereum.ledger.BlockQueue @@ -186,7 +186,7 @@ class CheckpointingServiceSpec trait TestSetup { val blockchain: BlockchainImpl = mock[BlockchainImpl] val blockchainReader: BlockchainReader = mock[BlockchainReader] - val bestChain: BlockchainBranch = mock[BlockchainBranch] + val bestChain: Branch = mock[Branch] (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(bestChain) val blockQueue: BlockQueue = mock[BlockQueue] val syncController: TestProbe = TestProbe() diff --git a/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala b/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala index 5f933fe801..f6d229b65e 100644 --- a/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala +++ b/src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala @@ -32,7 +32,7 @@ import io.iohk.ethereum.consensus.validators.BlockHeaderValidator import io.iohk.ethereum.crypto.generateKeyPair import io.iohk.ethereum.crypto.kec256 import io.iohk.ethereum.domain._ -import io.iohk.ethereum.domain.branch.BlockchainBranch +import io.iohk.ethereum.domain.branch.Branch import io.iohk.ethereum.ledger.BlockExecutionError.ValidationAfterExecError import io.iohk.ethereum.ledger.PC import io.iohk.ethereum.ledger.PR @@ -412,7 +412,7 @@ trait TestSetupWithVmAndValidators extends EphemBlockchainTestSetup { trait MockBlockchain extends MockFactory { self: TestSetupWithVmAndValidators => //+ cake overrides - val bestChain: BlockchainBranch = mock[BlockchainBranch] + val bestChain: Branch = mock[Branch] override lazy val blockchainReader: BlockchainReader = mock[BlockchainReader] override lazy val blockchainWriter: BlockchainWriter = mock[BlockchainWriter] (blockchainReader.getBestBranch _).expects().anyNumberOfTimes().returning(bestChain)