Skip to content

Commit 9a7f08e

Browse files
committed
[Kaizen] Unflake BlockImporterItSpec
1 parent 7456a31 commit 9a7f08e

File tree

1 file changed

+122
-129
lines changed

1 file changed

+122
-129
lines changed

src/it/scala/io/iohk/ethereum/ledger/BlockImporterItSpec.scala

Lines changed: 122 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,17 @@ package io.iohk.ethereum.ledger
33
import akka.actor.ActorRef
44
import akka.testkit.TestProbe
55
import akka.util.ByteString
6-
76
import cats.data.NonEmptyList
8-
97
import monix.execution.Scheduler
108
import monix.execution.schedulers.SchedulerService
119

1210
import scala.concurrent.duration._
13-
1411
import org.scalamock.scalatest.MockFactory
1512
import org.scalatest.BeforeAndAfterAll
1613
import org.scalatest.concurrent.Eventually
1714
import org.scalatest.flatspec.AnyFlatSpecLike
1815
import org.scalatest.matchers.should.Matchers
19-
20-
import io.iohk.ethereum.Fixtures
21-
import io.iohk.ethereum.Mocks
22-
import io.iohk.ethereum.NormalPatience
23-
import io.iohk.ethereum.ObjectGenerators
24-
import io.iohk.ethereum.Timeouts
16+
import io.iohk.ethereum.{Fixtures, Mocks, NormalPatience, ObjectGenerators, Timeouts, crypto}
2517
import io.iohk.ethereum.blockchain.sync.regular.BlockFetcher
2618
import io.iohk.ethereum.blockchain.sync.regular.BlockImporter
2719
import io.iohk.ethereum.blockchain.sync.regular.BlockImporter.NewCheckpoint
@@ -32,15 +24,13 @@ import io.iohk.ethereum.consensus.blocks.CheckpointBlockGenerator
3224
import io.iohk.ethereum.consensus.pow.validators.OmmersValidator
3325
import io.iohk.ethereum.consensus.pow.validators.StdOmmersValidator
3426
import io.iohk.ethereum.consensus.validators.Validators
35-
import io.iohk.ethereum.crypto
3627
import io.iohk.ethereum.domain._
3728
import io.iohk.ethereum.mpt.MerklePatriciaTrie
3829
import io.iohk.ethereum.utils.Config
3930
import io.iohk.ethereum.utils.Config.SyncConfig
4031

4132
class BlockImporterItSpec
4233
extends MockFactory
43-
with TestSetupWithVmAndValidators
4434
with AnyFlatSpecLike
4535
with Matchers
4636
with BeforeAndAfterAll
@@ -54,114 +44,9 @@ class BlockImporterItSpec
5444
testScheduler.awaitTermination(60.second)
5545
}
5646

57-
override lazy val blockQueue: BlockQueue = BlockQueue(blockchain, blockchainReader, SyncConfig(Config.config))
58-
59-
val genesis: Block = Block(
60-
Fixtures.Blocks.Genesis.header.copy(stateRoot = ByteString(MerklePatriciaTrie.EmptyRootHash)),
61-
Fixtures.Blocks.Genesis.body
62-
)
63-
val genesisWeight: ChainWeight = ChainWeight.zero.increase(genesis.header)
64-
65-
blockchainWriter.save(genesis, Seq(), genesisWeight, saveAsBestBlock = true)
66-
67-
lazy val checkpointBlockGenerator: CheckpointBlockGenerator = new CheckpointBlockGenerator
68-
69-
val fetcherProbe: TestProbe = TestProbe()
70-
val ommersPoolProbe: TestProbe = TestProbe()
71-
val broadcasterProbe: TestProbe = TestProbe()
72-
val pendingTransactionsManagerProbe: TestProbe = TestProbe()
73-
val supervisor: TestProbe = TestProbe()
74-
75-
val emptyWorld: InMemoryWorldStateProxy = InMemoryWorldStateProxy(
76-
storagesInstance.storages.evmCodeStorage,
77-
blockchain.getBackingMptStorage(-1),
78-
(number: BigInt) => blockchainReader.getBlockHeaderByNumber(number).map(_.hash),
79-
blockchainConfig.accountStartNonce,
80-
ByteString(MerklePatriciaTrie.EmptyRootHash),
81-
noEmptyAccounts = false,
82-
ethCompatibleStorage = true
83-
)
84-
85-
override protected lazy val successValidators: Validators = new Mocks.MockValidatorsAlwaysSucceed {
86-
override val ommersValidator: OmmersValidator = (
87-
parentHash: ByteString,
88-
blockNumber: BigInt,
89-
ommers: Seq[BlockHeader],
90-
getBlockHeaderByHash: GetBlockHeaderByHash,
91-
getNBlocksBack: GetNBlocksBack
92-
) =>
93-
new StdOmmersValidator(blockHeaderValidator)
94-
.validate(parentHash, blockNumber, ommers, getBlockHeaderByHash, getNBlocksBack)
95-
}
96-
97-
override lazy val blockImport: BlockImport = mkBlockImport(
98-
validators = successValidators,
99-
blockExecutionOpt = Some(
100-
new BlockExecution(
101-
blockchain,
102-
blockchainReader,
103-
blockchainWriter,
104-
storagesInstance.storages.evmCodeStorage,
105-
blockchainConfig,
106-
consensus.blockPreparator,
107-
new BlockValidation(consensus, blockchainReader, blockQueue)
108-
) {
109-
override def executeAndValidateBlock(
110-
block: Block,
111-
alreadyValidated: Boolean = false
112-
): Either[BlockExecutionError, Seq[Receipt]] =
113-
Right(BlockResult(emptyWorld).receipts)
114-
}
115-
)
116-
)
117-
// }
118-
119-
val blockImporter: ActorRef = system.actorOf(
120-
BlockImporter.props(
121-
fetcherProbe.ref,
122-
blockImport,
123-
blockchain,
124-
blockchainReader,
125-
storagesInstance.storages.stateStorage,
126-
new BranchResolution(blockchain, blockchainReader),
127-
syncConfig,
128-
ommersPoolProbe.ref,
129-
broadcasterProbe.ref,
130-
pendingTransactionsManagerProbe.ref,
131-
supervisor.ref
132-
)
133-
)
134-
135-
val genesisBlock = blockchainReader.genesisBlock
136-
val block1: Block = getBlock(genesisBlock.number + 1, parent = genesisBlock.header.hash)
137-
// new chain is shorter but has a higher weight
138-
val newBlock2: Block = getBlock(genesisBlock.number + 2, difficulty = 108, parent = block1.header.hash)
139-
val newBlock3: Block = getBlock(genesisBlock.number + 3, difficulty = 300, parent = newBlock2.header.hash)
140-
val oldBlock2: Block = getBlock(genesisBlock.number + 2, difficulty = 102, parent = block1.header.hash)
141-
val oldBlock3: Block = getBlock(genesisBlock.number + 3, difficulty = 103, parent = oldBlock2.header.hash)
142-
val oldBlock4: Block = getBlock(genesisBlock.number + 4, difficulty = 104, parent = oldBlock3.header.hash)
143-
144-
val weight1: ChainWeight = ChainWeight.totalDifficultyOnly(block1.header.difficulty)
145-
val newWeight2: ChainWeight = weight1.increase(newBlock2.header)
146-
val newWeight3: ChainWeight = newWeight2.increase(newBlock3.header)
147-
val oldWeight2: ChainWeight = weight1.increase(oldBlock2.header)
148-
val oldWeight3: ChainWeight = oldWeight2.increase(oldBlock3.header)
149-
val oldWeight4: ChainWeight = oldWeight3.increase(oldBlock4.header)
150-
151-
//saving initial main chain
152-
blockchainWriter.save(block1, Nil, weight1, saveAsBestBlock = true)
153-
blockchainWriter.save(oldBlock2, Nil, oldWeight2, saveAsBestBlock = true)
154-
blockchainWriter.save(oldBlock3, Nil, oldWeight3, saveAsBestBlock = true)
155-
blockchainWriter.save(oldBlock4, Nil, oldWeight4, saveAsBestBlock = true)
156-
157-
val oldBranch: List[Block] = List(oldBlock2, oldBlock3, oldBlock4)
158-
val newBranch: List[Block] = List(newBlock2, newBlock3)
159-
160-
blockImporter ! BlockImporter.Start
161-
162-
"BlockImporter" should "not discard blocks of the main chain if the reorganisation failed" in {
47+
"BlockImporter" should "not discard blocks of the main chain if the reorganisation failed" in new TestFixture() {
16348

164-
val blockImporter = system.actorOf(
49+
override val blockImporter = system.actorOf(
16550
BlockImporter.props(
16651
fetcherProbe.ref,
16752
mkBlockImport(validators = successValidators),
@@ -184,8 +69,7 @@ class BlockImporterItSpec
18469
eventually(blockchainReader.getBestBlock().get shouldEqual oldBlock4)
18570
}
18671

187-
it should "return a correct new best block after reorganising longer chain to a shorter one if its weight is bigger" in {
188-
72+
it should "return a correct new best block after reorganising longer chain to a shorter one if its weight is bigger" in new StartedImportFixture() {
18973
//returning discarded initial chain
19074
blockchainWriter.save(oldBlock2, Nil, oldWeight2, saveAsBestBlock = true)
19175
blockchainWriter.save(oldBlock3, Nil, oldWeight3, saveAsBestBlock = true)
@@ -196,7 +80,7 @@ class BlockImporterItSpec
19680
eventually(blockchainReader.getBestBlock().get shouldEqual newBlock3)
19781
}
19882

199-
it should "return Unknown branch, in case of PickedBlocks with block that has a parent that's not in the chain" in {
83+
it should "return Unknown branch, in case of PickedBlocks with block that has a parent that's not in the chain" in new StartedImportFixture() {
20084
val newBlock4ParentOldBlock3: Block =
20185
getBlock(genesisBlock.number + 4, difficulty = 104, parent = oldBlock3.header.hash)
20286
val newBlock4WeightParentOldBlock3 = oldWeight3.increase(newBlock4ParentOldBlock3.header)
@@ -223,35 +107,35 @@ class BlockImporterItSpec
223107
eventually(blockchainReader.getBestBlock().get shouldEqual newBlock4ParentOldBlock3)
224108
}
225109

226-
it should "switch to a branch with a checkpoint" in {
110+
it should "switch to a branch with a checkpoint" in new StartedImportFixture() {
227111

228112
val checkpoint = ObjectGenerators.fakeCheckpointGen(3, 3).sample.get
229113
val oldBlock5WithCheckpoint: Block = checkpointBlockGenerator.generate(oldBlock4, checkpoint)
230114
blockchainWriter.save(oldBlock5WithCheckpoint, Nil, oldWeight4, saveAsBestBlock = true)
231115

232-
val newBranch = List(newBlock2, newBlock3)
116+
override val newBranch = List(newBlock2, newBlock3)
233117

234118
blockImporter ! BlockFetcher.PickedBlocks(NonEmptyList.fromListUnsafe(newBranch))
235119

236120
eventually(blockchainReader.getBestBlock().get shouldEqual oldBlock5WithCheckpoint)
237121
eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual oldBlock5WithCheckpoint.header.number)
238122
}
239123

240-
it should "switch to a branch with a newer checkpoint" in {
124+
it should "switch to a branch with a newer checkpoint" in new StartedImportFixture() {
241125

242126
val checkpoint = ObjectGenerators.fakeCheckpointGen(3, 3).sample.get
243127
val newBlock4WithCheckpoint: Block = checkpointBlockGenerator.generate(newBlock3, checkpoint)
244128
blockchainWriter.save(newBlock4WithCheckpoint, Nil, newWeight3, saveAsBestBlock = true)
245129

246-
val newBranch = List(newBlock4WithCheckpoint)
130+
override val newBranch = List(newBlock4WithCheckpoint)
247131

248132
blockImporter ! BlockFetcher.PickedBlocks(NonEmptyList.fromListUnsafe(newBranch))
249133

250134
eventually(blockchainReader.getBestBlock().get shouldEqual newBlock4WithCheckpoint)
251135
eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual newBlock4WithCheckpoint.header.number)
252136
}
253137

254-
it should "return a correct checkpointed block after receiving a request for generating a new checkpoint" in {
138+
it should "return a correct checkpointed block after receiving a request for generating a new checkpoint" in new StartedImportFixture() {
255139

256140
val parent = blockchainReader.getBestBlock().get
257141
val newBlock5: Block = getBlock(genesisBlock.number + 5, difficulty = 104, parent = parent.header.hash)
@@ -270,12 +154,12 @@ class BlockImporterItSpec
270154
eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual newBlock5.header.number + 1)
271155
}
272156

273-
it should "ask BlockFetcher to resolve missing node" in {
157+
it should "ask BlockFetcher to resolve missing node" in new TestFixture() {
274158
val parent = blockchainReader.getBestBlock().get
275159
val newBlock: Block = getBlock(genesisBlock.number + 5, difficulty = 104, parent = parent.header.hash)
276160
val invalidBlock = newBlock.copy(header = newBlock.header.copy(beneficiary = Address(111).bytes))
277161

278-
val blockImporter = system.actorOf(
162+
override val blockImporter = system.actorOf(
279163
BlockImporter.props(
280164
fetcherProbe.ref,
281165
mkBlockImport(validators = successValidators),
@@ -296,7 +180,7 @@ class BlockImporterItSpec
296180

297181
eventually {
298182
val msg = fetcherProbe
299-
.fishForMessage(Timeouts.longTimeout) {
183+
.fishForMessage(Timeouts.normalTimeout) {
300184
case BlockFetcher.FetchStateNode(_, _) => true
301185
case _ => false
302186
}
@@ -307,3 +191,112 @@ class BlockImporterItSpec
307191

308192
}
309193
}
194+
195+
class TestFixture extends TestSetupWithVmAndValidators {
196+
197+
override lazy val blockQueue: BlockQueue = BlockQueue(blockchain, blockchainReader, SyncConfig(Config.config))
198+
199+
val genesis: Block = Block(
200+
Fixtures.Blocks.Genesis.header.copy(stateRoot = ByteString(MerklePatriciaTrie.EmptyRootHash)),
201+
Fixtures.Blocks.Genesis.body
202+
)
203+
val genesisWeight: ChainWeight = ChainWeight.zero.increase(genesis.header)
204+
205+
blockchainWriter.save(genesis, Seq(), genesisWeight, saveAsBestBlock = true)
206+
207+
lazy val checkpointBlockGenerator: CheckpointBlockGenerator = new CheckpointBlockGenerator
208+
209+
val fetcherProbe: TestProbe = TestProbe()
210+
val ommersPoolProbe: TestProbe = TestProbe()
211+
val broadcasterProbe: TestProbe = TestProbe()
212+
val pendingTransactionsManagerProbe: TestProbe = TestProbe()
213+
val supervisor: TestProbe = TestProbe()
214+
215+
val emptyWorld: InMemoryWorldStateProxy = InMemoryWorldStateProxy(
216+
storagesInstance.storages.evmCodeStorage,
217+
blockchain.getBackingMptStorage(-1),
218+
(number: BigInt) => blockchainReader.getBlockHeaderByNumber(number).map(_.hash),
219+
blockchainConfig.accountStartNonce,
220+
ByteString(MerklePatriciaTrie.EmptyRootHash),
221+
noEmptyAccounts = false,
222+
ethCompatibleStorage = true
223+
)
224+
225+
override protected lazy val successValidators: Validators = new Mocks.MockValidatorsAlwaysSucceed {
226+
override val ommersValidator: OmmersValidator = (
227+
parentHash: ByteString,
228+
blockNumber: BigInt,
229+
ommers: Seq[BlockHeader],
230+
getBlockHeaderByHash: GetBlockHeaderByHash,
231+
getNBlocksBack: GetNBlocksBack
232+
) =>
233+
new StdOmmersValidator(blockHeaderValidator)
234+
.validate(parentHash, blockNumber, ommers, getBlockHeaderByHash, getNBlocksBack)
235+
}
236+
237+
override lazy val blockImport: BlockImport = mkBlockImport(
238+
validators = successValidators,
239+
blockExecutionOpt = Some(
240+
new BlockExecution(
241+
blockchain,
242+
blockchainReader,
243+
blockchainWriter,
244+
storagesInstance.storages.evmCodeStorage,
245+
blockchainConfig,
246+
consensus.blockPreparator,
247+
new BlockValidation(consensus, blockchainReader, blockQueue)
248+
) {
249+
override def executeAndValidateBlock(
250+
block: Block,
251+
alreadyValidated: Boolean = false
252+
): Either[BlockExecutionError, Seq[Receipt]] =
253+
Right(BlockResult(emptyWorld).receipts)
254+
}
255+
)
256+
)
257+
258+
val blockImporter: ActorRef = system.actorOf(
259+
BlockImporter.props(
260+
fetcherProbe.ref,
261+
blockImport,
262+
blockchain,
263+
blockchainReader,
264+
storagesInstance.storages.stateStorage,
265+
new BranchResolution(blockchain, blockchainReader),
266+
syncConfig,
267+
ommersPoolProbe.ref,
268+
broadcasterProbe.ref,
269+
pendingTransactionsManagerProbe.ref,
270+
supervisor.ref
271+
)
272+
)
273+
274+
val genesisBlock = blockchainReader.genesisBlock
275+
val block1: Block = getBlock(genesisBlock.number + 1, parent = genesisBlock.header.hash)
276+
// new chain is shorter but has a higher weight
277+
val newBlock2: Block = getBlock(genesisBlock.number + 2, difficulty = 108, parent = block1.header.hash)
278+
val newBlock3: Block = getBlock(genesisBlock.number + 3, difficulty = 300, parent = newBlock2.header.hash)
279+
val oldBlock2: Block = getBlock(genesisBlock.number + 2, difficulty = 102, parent = block1.header.hash)
280+
val oldBlock3: Block = getBlock(genesisBlock.number + 3, difficulty = 103, parent = oldBlock2.header.hash)
281+
val oldBlock4: Block = getBlock(genesisBlock.number + 4, difficulty = 104, parent = oldBlock3.header.hash)
282+
283+
val weight1: ChainWeight = ChainWeight.totalDifficultyOnly(block1.header.difficulty)
284+
val newWeight2: ChainWeight = weight1.increase(newBlock2.header)
285+
val newWeight3: ChainWeight = newWeight2.increase(newBlock3.header)
286+
val oldWeight2: ChainWeight = weight1.increase(oldBlock2.header)
287+
val oldWeight3: ChainWeight = oldWeight2.increase(oldBlock3.header)
288+
val oldWeight4: ChainWeight = oldWeight3.increase(oldBlock4.header)
289+
290+
//saving initial main chain
291+
blockchainWriter.save(block1, Nil, weight1, saveAsBestBlock = true)
292+
blockchainWriter.save(oldBlock2, Nil, oldWeight2, saveAsBestBlock = true)
293+
blockchainWriter.save(oldBlock3, Nil, oldWeight3, saveAsBestBlock = true)
294+
blockchainWriter.save(oldBlock4, Nil, oldWeight4, saveAsBestBlock = true)
295+
296+
val oldBranch: List[Block] = List(oldBlock2, oldBlock3, oldBlock4)
297+
val newBranch: List[Block] = List(newBlock2, newBlock3)
298+
}
299+
300+
class StartedImportFixture extends TestFixture {
301+
blockImporter ! BlockImporter.Start
302+
}

0 commit comments

Comments
 (0)