@@ -40,7 +40,6 @@ import io.iohk.ethereum.utils.Config.SyncConfig
4040
4141class BlockImporterItSpec
4242 extends MockFactory
43- with TestSetupWithVmAndValidators
4443 with AnyFlatSpecLike
4544 with Matchers
4645 with BeforeAndAfterAll
@@ -54,114 +53,9 @@ class BlockImporterItSpec
5453 testScheduler.awaitTermination(60 .second)
5554 }
5655
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- // }
56+ " BlockImporter" should " not discard blocks of the main chain if the reorganisation failed" in new TestFixture () {
11857
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 {
163-
164- val blockImporter = system.actorOf(
58+ override val blockImporter = system.actorOf(
16559 BlockImporter .props(
16660 fetcherProbe.ref,
16761 mkBlockImport(validators = successValidators),
@@ -184,8 +78,7 @@ class BlockImporterItSpec
18478 eventually(blockchainReader.getBestBlock().get shouldEqual oldBlock4)
18579 }
18680
187- it should " return a correct new best block after reorganising longer chain to a shorter one if its weight is bigger" in {
188-
81+ it should " return a correct new best block after reorganising longer chain to a shorter one if its weight is bigger" in new StartedImportFixture () {
18982 // returning discarded initial chain
19083 blockchainWriter.save(oldBlock2, Nil , oldWeight2, saveAsBestBlock = true )
19184 blockchainWriter.save(oldBlock3, Nil , oldWeight3, saveAsBestBlock = true )
@@ -196,7 +89,7 @@ class BlockImporterItSpec
19689 eventually(blockchainReader.getBestBlock().get shouldEqual newBlock3)
19790 }
19891
199- it should " return Unknown branch, in case of PickedBlocks with block that has a parent that's not in the chain" in {
92+ it should " return Unknown branch, in case of PickedBlocks with block that has a parent that's not in the chain" in new StartedImportFixture () {
20093 val newBlock4ParentOldBlock3 : Block =
20194 getBlock(genesisBlock.number + 4 , difficulty = 104 , parent = oldBlock3.header.hash)
20295 val newBlock4WeightParentOldBlock3 = oldWeight3.increase(newBlock4ParentOldBlock3.header)
@@ -223,35 +116,35 @@ class BlockImporterItSpec
223116 eventually(blockchainReader.getBestBlock().get shouldEqual newBlock4ParentOldBlock3)
224117 }
225118
226- it should " switch to a branch with a checkpoint" in {
119+ it should " switch to a branch with a checkpoint" in new StartedImportFixture () {
227120
228121 val checkpoint = ObjectGenerators .fakeCheckpointGen(3 , 3 ).sample.get
229122 val oldBlock5WithCheckpoint : Block = checkpointBlockGenerator.generate(oldBlock4, checkpoint)
230123 blockchainWriter.save(oldBlock5WithCheckpoint, Nil , oldWeight4, saveAsBestBlock = true )
231124
232- val newBranch = List (newBlock2, newBlock3)
125+ override val newBranch = List (newBlock2, newBlock3)
233126
234127 blockImporter ! BlockFetcher .PickedBlocks (NonEmptyList .fromListUnsafe(newBranch))
235128
236129 eventually(blockchainReader.getBestBlock().get shouldEqual oldBlock5WithCheckpoint)
237130 eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual oldBlock5WithCheckpoint.header.number)
238131 }
239132
240- it should " switch to a branch with a newer checkpoint" in {
133+ it should " switch to a branch with a newer checkpoint" in new StartedImportFixture () {
241134
242135 val checkpoint = ObjectGenerators .fakeCheckpointGen(3 , 3 ).sample.get
243136 val newBlock4WithCheckpoint : Block = checkpointBlockGenerator.generate(newBlock3, checkpoint)
244137 blockchainWriter.save(newBlock4WithCheckpoint, Nil , newWeight3, saveAsBestBlock = true )
245138
246- val newBranch = List (newBlock4WithCheckpoint)
139+ override val newBranch = List (newBlock4WithCheckpoint)
247140
248141 blockImporter ! BlockFetcher .PickedBlocks (NonEmptyList .fromListUnsafe(newBranch))
249142
250143 eventually(blockchainReader.getBestBlock().get shouldEqual newBlock4WithCheckpoint)
251144 eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual newBlock4WithCheckpoint.header.number)
252145 }
253146
254- it should " return a correct checkpointed block after receiving a request for generating a new checkpoint" in {
147+ it should " return a correct checkpointed block after receiving a request for generating a new checkpoint" in new StartedImportFixture () {
255148
256149 val parent = blockchainReader.getBestBlock().get
257150 val newBlock5 : Block = getBlock(genesisBlock.number + 5 , difficulty = 104 , parent = parent.header.hash)
@@ -270,12 +163,12 @@ class BlockImporterItSpec
270163 eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual newBlock5.header.number + 1 )
271164 }
272165
273- it should " ask BlockFetcher to resolve missing node" in {
166+ it should " ask BlockFetcher to resolve missing node" in new TestFixture () {
274167 val parent = blockchainReader.getBestBlock().get
275168 val newBlock : Block = getBlock(genesisBlock.number + 5 , difficulty = 104 , parent = parent.header.hash)
276169 val invalidBlock = newBlock.copy(header = newBlock.header.copy(beneficiary = Address (111 ).bytes))
277170
278- val blockImporter = system.actorOf(
171+ override val blockImporter = system.actorOf(
279172 BlockImporter .props(
280173 fetcherProbe.ref,
281174 mkBlockImport(validators = successValidators),
@@ -296,7 +189,7 @@ class BlockImporterItSpec
296189
297190 eventually {
298191 val msg = fetcherProbe
299- .fishForMessage(Timeouts .longTimeout ) {
192+ .fishForMessage(Timeouts .normalTimeout ) {
300193 case BlockFetcher .FetchStateNode (_, _) => true
301194 case _ => false
302195 }
@@ -307,3 +200,112 @@ class BlockImporterItSpec
307200
308201 }
309202}
203+
204+ class TestFixture extends TestSetupWithVmAndValidators {
205+
206+ override lazy val blockQueue : BlockQueue = BlockQueue (blockchain, blockchainReader, SyncConfig (Config .config))
207+
208+ val genesis : Block = Block (
209+ Fixtures .Blocks .Genesis .header.copy(stateRoot = ByteString (MerklePatriciaTrie .EmptyRootHash )),
210+ Fixtures .Blocks .Genesis .body
211+ )
212+ val genesisWeight : ChainWeight = ChainWeight .zero.increase(genesis.header)
213+
214+ blockchainWriter.save(genesis, Seq (), genesisWeight, saveAsBestBlock = true )
215+
216+ lazy val checkpointBlockGenerator : CheckpointBlockGenerator = new CheckpointBlockGenerator
217+
218+ val fetcherProbe : TestProbe = TestProbe ()
219+ val ommersPoolProbe : TestProbe = TestProbe ()
220+ val broadcasterProbe : TestProbe = TestProbe ()
221+ val pendingTransactionsManagerProbe : TestProbe = TestProbe ()
222+ val supervisor : TestProbe = TestProbe ()
223+
224+ val emptyWorld : InMemoryWorldStateProxy = InMemoryWorldStateProxy (
225+ storagesInstance.storages.evmCodeStorage,
226+ blockchain.getBackingMptStorage(- 1 ),
227+ (number : BigInt ) => blockchainReader.getBlockHeaderByNumber(number).map(_.hash),
228+ blockchainConfig.accountStartNonce,
229+ ByteString (MerklePatriciaTrie .EmptyRootHash ),
230+ noEmptyAccounts = false ,
231+ ethCompatibleStorage = true
232+ )
233+
234+ override protected lazy val successValidators : Validators = new Mocks .MockValidatorsAlwaysSucceed {
235+ override val ommersValidator : OmmersValidator = (
236+ parentHash : ByteString ,
237+ blockNumber : BigInt ,
238+ ommers : Seq [BlockHeader ],
239+ getBlockHeaderByHash : GetBlockHeaderByHash ,
240+ getNBlocksBack : GetNBlocksBack
241+ ) =>
242+ new StdOmmersValidator (blockHeaderValidator)
243+ .validate(parentHash, blockNumber, ommers, getBlockHeaderByHash, getNBlocksBack)
244+ }
245+
246+ override lazy val blockImport : BlockImport = mkBlockImport(
247+ validators = successValidators,
248+ blockExecutionOpt = Some (
249+ new BlockExecution (
250+ blockchain,
251+ blockchainReader,
252+ blockchainWriter,
253+ storagesInstance.storages.evmCodeStorage,
254+ blockchainConfig,
255+ consensus.blockPreparator,
256+ new BlockValidation (consensus, blockchainReader, blockQueue)
257+ ) {
258+ override def executeAndValidateBlock (
259+ block : Block ,
260+ alreadyValidated : Boolean = false
261+ ): Either [BlockExecutionError , Seq [Receipt ]] =
262+ Right (BlockResult (emptyWorld).receipts)
263+ }
264+ )
265+ )
266+
267+ val blockImporter : ActorRef = system.actorOf(
268+ BlockImporter .props(
269+ fetcherProbe.ref,
270+ blockImport,
271+ blockchain,
272+ blockchainReader,
273+ storagesInstance.storages.stateStorage,
274+ new BranchResolution (blockchain, blockchainReader),
275+ syncConfig,
276+ ommersPoolProbe.ref,
277+ broadcasterProbe.ref,
278+ pendingTransactionsManagerProbe.ref,
279+ supervisor.ref
280+ )
281+ )
282+
283+ val genesisBlock = blockchainReader.genesisBlock
284+ val block1 : Block = getBlock(genesisBlock.number + 1 , parent = genesisBlock.header.hash)
285+ // new chain is shorter but has a higher weight
286+ val newBlock2 : Block = getBlock(genesisBlock.number + 2 , difficulty = 108 , parent = block1.header.hash)
287+ val newBlock3 : Block = getBlock(genesisBlock.number + 3 , difficulty = 300 , parent = newBlock2.header.hash)
288+ val oldBlock2 : Block = getBlock(genesisBlock.number + 2 , difficulty = 102 , parent = block1.header.hash)
289+ val oldBlock3 : Block = getBlock(genesisBlock.number + 3 , difficulty = 103 , parent = oldBlock2.header.hash)
290+ val oldBlock4 : Block = getBlock(genesisBlock.number + 4 , difficulty = 104 , parent = oldBlock3.header.hash)
291+
292+ val weight1 : ChainWeight = ChainWeight .totalDifficultyOnly(block1.header.difficulty)
293+ val newWeight2 : ChainWeight = weight1.increase(newBlock2.header)
294+ val newWeight3 : ChainWeight = newWeight2.increase(newBlock3.header)
295+ val oldWeight2 : ChainWeight = weight1.increase(oldBlock2.header)
296+ val oldWeight3 : ChainWeight = oldWeight2.increase(oldBlock3.header)
297+ val oldWeight4 : ChainWeight = oldWeight3.increase(oldBlock4.header)
298+
299+ // saving initial main chain
300+ blockchainWriter.save(block1, Nil , weight1, saveAsBestBlock = true )
301+ blockchainWriter.save(oldBlock2, Nil , oldWeight2, saveAsBestBlock = true )
302+ blockchainWriter.save(oldBlock3, Nil , oldWeight3, saveAsBestBlock = true )
303+ blockchainWriter.save(oldBlock4, Nil , oldWeight4, saveAsBestBlock = true )
304+
305+ val oldBranch : List [Block ] = List (oldBlock2, oldBlock3, oldBlock4)
306+ val newBranch : List [Block ] = List (newBlock2, newBlock3)
307+ }
308+
309+ class StartedImportFixture extends TestFixture {
310+ blockImporter ! BlockImporter .Start
311+ }
0 commit comments