@@ -4,11 +4,7 @@ import java.net.InetSocketAddress
4
4
import akka .actor .ActorSystem
5
5
import akka .testkit .{TestKit , TestProbe }
6
6
import com .miguno .akka .testing .VirtualTime
7
- import io .iohk .ethereum .Mocks .{
8
- MockValidatorsAlwaysSucceed ,
9
- MockValidatorsFailingOnBlockBodies ,
10
- MockValidatorsFailOnSpecificBlockNumber
11
- }
7
+ import io .iohk .ethereum .Mocks .{MockValidatorsAlwaysSucceed , MockValidatorsFailingOnBlockBodies }
12
8
import io .iohk .ethereum .BlockHelpers
13
9
import io .iohk .ethereum .Fixtures .{Blocks => FixtureBlocks }
14
10
import io .iohk .ethereum .blockchain .sync .PeersClient .BlacklistPeer
@@ -129,7 +125,7 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
129
125
peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == firstGetBlockHeadersRequest => () }
130
126
}
131
127
132
- " should not append new blocks if the received data does not match" in new TestSetup {
128
+ " should not enqueue requested blocks if the received bodies does not match" in new TestSetup {
133
129
134
130
// Important: Here we are forcing the mismatch between request headers and received bodies
135
131
override lazy val validators = new MockValidatorsFailingOnBlockBodies
@@ -151,8 +147,14 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
151
147
val getBlockBodiesResponse = BlockBodies (chain.map(_.body))
152
148
peersClient.reply(PeersClient .Response (fakePeer, getBlockBodiesResponse))
153
149
150
+ // Fetcher should blacklist the peer and retry asking for the same bodies
154
151
peersClient.expectMsgClass(classOf [BlacklistPeer ])
155
152
peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest => () }
153
+
154
+ // Fetcher should not enqueue any new block
155
+ importer.send(blockFetcher, PickBlocks (syncConfig.blocksBatchSize))
156
+ importer.ignoreMsg({ case BlockImporter .NotOnTop => true })
157
+ importer.expectNoMessage()
156
158
}
157
159
158
160
" should be able to handle block bodies received in several parts" in new TestSetup {
@@ -172,13 +174,13 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
172
174
peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest1 => () }
173
175
174
176
// It will receive all the requested bodies, but splitted in 2 parts.
175
- val (subChain1, subChain2) = chain.splitAt(syncConfig.blockHeadersPerRequest / 2 )
177
+ val (subChain1, subChain2) = chain.splitAt(syncConfig.blockBodiesPerRequest / 2 )
176
178
177
179
val getBlockBodiesResponse1 = BlockBodies (subChain1.map(_.body))
178
180
peersClient.reply(PeersClient .Response (fakePeer, getBlockBodiesResponse1))
179
181
180
182
val getBlockHeadersRequest2 =
181
- GetBlockHeaders (Left (subChain1 .last.number + 1 ), syncConfig.blockHeadersPerRequest, skip = 0 , reverse = false )
183
+ GetBlockHeaders (Left (chain .last.number + 1 ), syncConfig.blockHeadersPerRequest, skip = 0 , reverse = false )
182
184
peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockHeadersRequest2 => () }
183
185
184
186
val getBlockBodiesRequest2 = GetBlockBodies (subChain2.map(_.hash))
@@ -188,13 +190,15 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
188
190
peersClient.reply(PeersClient .Response (fakePeer, getBlockBodiesResponse2))
189
191
190
192
peersClient.expectNoMessage()
191
- }
192
193
193
- " should ignore response, without blacklist the peer, in case a sub ordered block bodies chain is received" in new TestSetup {
194
+ importer.send(blockFetcher, PickBlocks (chain.size))
195
+ importer.ignoreMsg({ case BlockImporter .NotOnTop => true })
196
+ importer.expectMsgPF() { case BlockFetcher .PickedBlocks (blocks) =>
197
+ blocks.map(_.hash).toList shouldEqual chain.map(_.hash)
198
+ }
199
+ }
194
200
195
- // Important: Here (in a hacky way) we are enforcing received bodies
196
- // to be a sub ordered chain that fetcher can't append given their current state
197
- override lazy val validators = new MockValidatorsFailOnSpecificBlockNumber (1 )
201
+ " should stop requesting, without blacklist the peer, in case empty bodies are received" in new TestSetup {
198
202
199
203
startFetcher()
200
204
@@ -210,12 +214,31 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
210
214
val getBlockBodiesRequest1 = GetBlockBodies (chain.map(_.hash))
211
215
peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest1 => () }
212
216
213
- val (subChain1, _) = chain.splitAt(syncConfig.blockHeadersPerRequest / 2 )
217
+ // It will receive part of the requested bodies.
218
+ val (subChain1, subChain2) = chain.splitAt(syncConfig.blockBodiesPerRequest / 2 )
214
219
215
220
val getBlockBodiesResponse1 = BlockBodies (subChain1.map(_.body))
216
221
peersClient.reply(PeersClient .Response (fakePeer, getBlockBodiesResponse1))
217
222
218
- peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest1 => () }
223
+ val getBlockHeadersRequest2 =
224
+ GetBlockHeaders (Left (chain.last.number + 1 ), syncConfig.blockHeadersPerRequest, skip = 0 , reverse = false )
225
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockHeadersRequest2 => () }
226
+
227
+ val getBlockBodiesRequest2 = GetBlockBodies (subChain2.map(_.hash))
228
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest2 => () }
229
+
230
+ // We receive empty bodies instead of the second part
231
+ val getBlockBodiesResponse2 = BlockBodies (List ())
232
+ peersClient.reply(PeersClient .Response (fakePeer, getBlockBodiesResponse2))
233
+
234
+ peersClient.expectNoMessage()
235
+
236
+ // If we try to pick the whole chain we should only receive the first part
237
+ importer.send(blockFetcher, PickBlocks (chain.size))
238
+ importer.ignoreMsg({ case BlockImporter .NotOnTop => true })
239
+ importer.expectMsgPF() { case BlockFetcher .PickedBlocks (blocks) =>
240
+ blocks.map(_.hash).toList shouldEqual subChain1.map(_.hash)
241
+ }
219
242
}
220
243
221
244
" should ensure blocks passed to importer are always forming chain" in new TestSetup {
0 commit comments