Skip to content

Commit 4a7e5cc

Browse files
pslaskibsuieric
authored andcommitted
etcm-678 etcm-660 fix for removing chain after the node restart
1 parent cba4321 commit 4a7e5cc

File tree

5 files changed

+36
-14
lines changed

5 files changed

+36
-14
lines changed

src/main/scala/io/iohk/ethereum/domain/Blockchain.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,19 @@ trait Blockchain {
215215
def getStateStorage: StateStorage
216216

217217
def mptStateSavedKeys(): Observable[Either[IterationError, ByteString]]
218+
219+
/**
220+
* Strict check if given block hash is in chain
221+
* Using any of getXXXByHash is not always accurate - after restart the best block is often lower than before restart
222+
* The result of that is returning data of blocks which we don't consider as a part of the chain anymore
223+
* @param hash block hash
224+
*/
225+
def isInChain(hash: ByteString): Boolean = {
226+
(for {
227+
header <- getBlockHeaderByHash(hash) if header.number <= getBestBlockNumber()
228+
hash <- getHashByBlockNumber(header.number)
229+
} yield header.hash == hash).getOrElse(false)
230+
}
218231
}
219232
// scalastyle:on
220233

src/main/scala/io/iohk/ethereum/ledger/BranchResolution.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ class BranchResolution(blockchain: Blockchain) extends Logger {
1111
InvalidBranch
1212
} else {
1313
val knownParentOrGenesis = blockchain
14-
.getBlockHeaderByHash(headers.head.parentHash)
15-
.isDefined || headers.head.hash == blockchain.genesisHeader.hash
14+
.isInChain(headers.head.parentHash) || headers.head.hash == blockchain.genesisHeader.hash
1615

1716
if (!knownParentOrGenesis)
1817
UnknownBranch

src/test/scala/io/iohk/ethereum/domain/BlockchainSpec.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ class BlockchainSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyCh
4444
assert(validBlock == block.get)
4545
}
4646

47+
it should "be able to do strict check of block existence in the chain" in new EphemBlockchainTestSetup {
48+
val validBlock = Fixtures.Blocks.ValidBlock.block
49+
blockchain.save(validBlock, Seq.empty, ChainWeight(100, 100), saveAsBestBlock = true)
50+
assert(blockchain.isInChain(validBlock.hash))
51+
// simulation of node restart
52+
blockchain.saveBestKnownBlocks(validBlock.header.number - 1)
53+
assert(!blockchain.isInChain(validBlock.hash))
54+
}
55+
4756
it should "be able to query a stored blockHeader by it's number" in new EphemBlockchainTestSetup {
4857
val validHeader = Fixtures.Blocks.ValidBlock.header
4958
blockchain.storeBlockHeader(validHeader).commit()

src/test/scala/io/iohk/ethereum/ledger/BranchResolutionSpec.scala

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ class BranchResolutionSpec
4141
val headers = getChainHeadersNel(5, 10)
4242

4343
setGenesisHeader(genesisHeader) // Check genesis block
44-
setBestBlockNumber(10)
45-
setHeaderByHash(headers.head.parentHash, None)
44+
setHeaderInChain(headers.head.parentHash, result = false)
4645

4746
ledger.resolveBranch(headers) shouldEqual UnknownBranch
4847
}
@@ -52,21 +51,21 @@ class BranchResolutionSpec
5251
val headers = getChainHeadersNel(1, 10)
5352

5453
setBestBlockNumber(10)
55-
setHeaderByHash(headers.head.parentHash, Some(getBlock(0).header))
54+
setHeaderInChain(headers.head.parentHash)
5655
setChainWeightByHash(headers.head.parentHash, ChainWeight.zero)
5756

5857
val oldBlocks = getChain(1, 10, headers.head.parentHash, headers.head.difficulty - 1)
5958
oldBlocks.map(b => setBlockByNumber(b.header.number, Some(b)))
6059

61-
ledger.resolveBranch(headers) shouldEqual NewBetterBranch(oldBlocks.toList)
60+
ledger.resolveBranch(headers) shouldEqual NewBetterBranch(oldBlocks)
6261
}
6362

6463
"report no need for a chain switch the headers do not have chain weight greater than currently known branch" in
6564
new BranchResolutionTestSetup {
6665
val headers = getChainHeadersNel(1, 10)
6766

6867
setBestBlockNumber(10)
69-
setHeaderByHash(headers.head.parentHash, Some(getBlock(0).header))
68+
setHeaderInChain(headers.head.parentHash)
7069
setChainWeightByHash(headers.head.parentHash, ChainWeight.zero)
7170

7271
val oldBlocks = getChain(1, 10, headers.head.parentHash, headers.head.difficulty)
@@ -78,6 +77,7 @@ class BranchResolutionSpec
7877
"correctly handle a branch that goes up to the genesis block" in new BranchResolutionTestSetup {
7978
val headers = genesisHeader :: getChainHeadersNel(1, 10, genesisHeader.hash)
8079

80+
setHeaderInChain(genesisHeader.parentHash, result = false)
8181
setGenesisHeader(genesisHeader)
8282
setBestBlockNumber(10)
8383
setChainWeightByHash(genesisHeader.hash, ChainWeight.zero)
@@ -93,6 +93,7 @@ class BranchResolutionSpec
9393
val differentGenesis: BlockHeader = genesisHeader.copy(extraData = ByteString("I'm different ;("))
9494
val headers = differentGenesis :: getChainHeadersNel(1, 10, differentGenesis.hash)
9595

96+
setHeaderInChain(differentGenesis.parentHash, result = false)
9697
setGenesisHeader(genesisHeader)
9798
setBestBlockNumber(10)
9899

@@ -104,7 +105,7 @@ class BranchResolutionSpec
104105
val commonParent = headers.toList(1)
105106

106107
setBestBlockNumber(8)
107-
setHeaderByHash(headers.head.parentHash, Some(getBlock(0).header))
108+
setHeaderInChain(headers.head.parentHash)
108109
setChainWeightByHash(commonParent.hash, ChainWeight.zero)
109110

110111
val oldBlocks = getChain(3, 8, commonParent.hash)
@@ -123,7 +124,7 @@ class BranchResolutionSpec
123124
val longerBranchLowerWeight = getChain(2, 10, commonParent.hash, difficulty = 100)
124125
val shorterBranchHigherWeight = getChainNel(2, 8, commonParent.hash, difficulty = 200)
125126

126-
setHeaderByHash(commonParent.hash, Some(commonParent.header))
127+
setHeaderInChain(commonParent.hash)
127128
setChainWeightForBlock(commonParent, parentWeight)
128129
setBestBlockNumber(longerBranchLowerWeight.last.number)
129130
longerBranchLowerWeight.foreach(b => setBlockByNumber(b.number, Some(b)))
@@ -150,7 +151,7 @@ class BranchResolutionSpec
150151

151152
val noCheckpointBranch = getChain(2, checkpointBranchLength + 2, commonParent.hash)
152153

153-
setHeaderByHash(commonParent.hash, Some(commonParent.header))
154+
setHeaderInChain(commonParent.hash)
154155
setChainWeightForBlock(commonParent, parentWeight)
155156
setBestBlockNumber(noCheckpointBranch.last.number)
156157
noCheckpointBranch.foreach(b => setBlockByNumber(b.number, Some(b)))
@@ -176,7 +177,7 @@ class BranchResolutionSpec
176177

177178
val noCheckpointBranch = getChainNel(2, checkpointBranchLength + 2, commonParent.hash)
178179

179-
setHeaderByHash(commonParent.hash, Some(commonParent.header))
180+
setHeaderInChain(commonParent.hash)
180181
setChainWeightForBlock(commonParent, parentWeight)
181182
setBestBlockNumber(checkpointBranch.last.number)
182183
checkpointBranch.map(b => setBlockByNumber(b.number, Some(b)))

src/test/scala/io/iohk/ethereum/ledger/LedgerTestSetup.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,15 +393,15 @@ trait MockBlockchain extends MockFactory { self: TestSetupWithVmAndValidators =>
393393
.once()
394394
}
395395

396-
def setHeaderByHash(hash: ByteString, header: Option[BlockHeader]): CallHandler1[ByteString, Option[BlockHeader]] =
397-
(blockchain.getBlockHeaderByHash _).expects(hash).returning(header)
396+
def setHeaderInChain(hash: ByteString, result: Boolean = true): CallHandler1[ByteString, Boolean] = {
397+
(blockchain.isInChain _).expects(hash).returning(result)
398+
}
398399

399400
def setBlockByNumber(number: BigInt, block: Option[Block]): CallHandler1[BigInt, Option[Block]] =
400401
(blockchain.getBlockByNumber _).expects(number).returning(block)
401402

402403
def setGenesisHeader(header: BlockHeader): Unit = {
403404
(() => blockchain.genesisHeader).expects().returning(header)
404-
setHeaderByHash(header.parentHash, None)
405405
}
406406
}
407407

0 commit comments

Comments
 (0)