@@ -40,7 +40,6 @@ import io.iohk.ethereum.utils.Config.SyncConfig
40
40
41
41
class BlockImporterItSpec
42
42
extends MockFactory
43
- with TestSetupWithVmAndValidators
44
43
with AnyFlatSpecLike
45
44
with Matchers
46
45
with BeforeAndAfterAll
@@ -54,114 +53,9 @@ class BlockImporterItSpec
54
53
testScheduler.awaitTermination(60 .second)
55
54
}
56
55
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 () {
118
57
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(
165
59
BlockImporter .props(
166
60
fetcherProbe.ref,
167
61
mkBlockImport(validators = successValidators),
@@ -184,8 +78,7 @@ class BlockImporterItSpec
184
78
eventually(blockchainReader.getBestBlock().get shouldEqual oldBlock4)
185
79
}
186
80
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 () {
189
82
// returning discarded initial chain
190
83
blockchainWriter.save(oldBlock2, Nil , oldWeight2, saveAsBestBlock = true )
191
84
blockchainWriter.save(oldBlock3, Nil , oldWeight3, saveAsBestBlock = true )
@@ -196,7 +89,7 @@ class BlockImporterItSpec
196
89
eventually(blockchainReader.getBestBlock().get shouldEqual newBlock3)
197
90
}
198
91
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 () {
200
93
val newBlock4ParentOldBlock3 : Block =
201
94
getBlock(genesisBlock.number + 4 , difficulty = 104 , parent = oldBlock3.header.hash)
202
95
val newBlock4WeightParentOldBlock3 = oldWeight3.increase(newBlock4ParentOldBlock3.header)
@@ -223,35 +116,35 @@ class BlockImporterItSpec
223
116
eventually(blockchainReader.getBestBlock().get shouldEqual newBlock4ParentOldBlock3)
224
117
}
225
118
226
- it should " switch to a branch with a checkpoint" in {
119
+ it should " switch to a branch with a checkpoint" in new StartedImportFixture () {
227
120
228
121
val checkpoint = ObjectGenerators .fakeCheckpointGen(3 , 3 ).sample.get
229
122
val oldBlock5WithCheckpoint : Block = checkpointBlockGenerator.generate(oldBlock4, checkpoint)
230
123
blockchainWriter.save(oldBlock5WithCheckpoint, Nil , oldWeight4, saveAsBestBlock = true )
231
124
232
- val newBranch = List (newBlock2, newBlock3)
125
+ override val newBranch = List (newBlock2, newBlock3)
233
126
234
127
blockImporter ! BlockFetcher .PickedBlocks (NonEmptyList .fromListUnsafe(newBranch))
235
128
236
129
eventually(blockchainReader.getBestBlock().get shouldEqual oldBlock5WithCheckpoint)
237
130
eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual oldBlock5WithCheckpoint.header.number)
238
131
}
239
132
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 () {
241
134
242
135
val checkpoint = ObjectGenerators .fakeCheckpointGen(3 , 3 ).sample.get
243
136
val newBlock4WithCheckpoint : Block = checkpointBlockGenerator.generate(newBlock3, checkpoint)
244
137
blockchainWriter.save(newBlock4WithCheckpoint, Nil , newWeight3, saveAsBestBlock = true )
245
138
246
- val newBranch = List (newBlock4WithCheckpoint)
139
+ override val newBranch = List (newBlock4WithCheckpoint)
247
140
248
141
blockImporter ! BlockFetcher .PickedBlocks (NonEmptyList .fromListUnsafe(newBranch))
249
142
250
143
eventually(blockchainReader.getBestBlock().get shouldEqual newBlock4WithCheckpoint)
251
144
eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual newBlock4WithCheckpoint.header.number)
252
145
}
253
146
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 () {
255
148
256
149
val parent = blockchainReader.getBestBlock().get
257
150
val newBlock5 : Block = getBlock(genesisBlock.number + 5 , difficulty = 104 , parent = parent.header.hash)
@@ -270,12 +163,12 @@ class BlockImporterItSpec
270
163
eventually(blockchain.getLatestCheckpointBlockNumber() shouldEqual newBlock5.header.number + 1 )
271
164
}
272
165
273
- it should " ask BlockFetcher to resolve missing node" in {
166
+ it should " ask BlockFetcher to resolve missing node" in new TestFixture () {
274
167
val parent = blockchainReader.getBestBlock().get
275
168
val newBlock : Block = getBlock(genesisBlock.number + 5 , difficulty = 104 , parent = parent.header.hash)
276
169
val invalidBlock = newBlock.copy(header = newBlock.header.copy(beneficiary = Address (111 ).bytes))
277
170
278
- val blockImporter = system.actorOf(
171
+ override val blockImporter = system.actorOf(
279
172
BlockImporter .props(
280
173
fetcherProbe.ref,
281
174
mkBlockImport(validators = successValidators),
@@ -296,7 +189,7 @@ class BlockImporterItSpec
296
189
297
190
eventually {
298
191
val msg = fetcherProbe
299
- .fishForMessage(Timeouts .longTimeout ) {
192
+ .fishForMessage(Timeouts .normalTimeout ) {
300
193
case BlockFetcher .FetchStateNode (_, _) => true
301
194
case _ => false
302
195
}
@@ -307,3 +200,112 @@ class BlockImporterItSpec
307
200
308
201
}
309
202
}
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