@@ -5,7 +5,11 @@ import java.net.InetSocketAddress
5
5
import akka .actor .ActorSystem
6
6
import akka .testkit .{TestKit , TestProbe }
7
7
import com .miguno .akka .testing .VirtualTime
8
- import io .iohk .ethereum .Mocks .{MockValidatorsAlwaysSucceed , MockValidatorsFailingOnBlockBodies }
8
+ import io .iohk .ethereum .Mocks .{
9
+ MockValidatorsAlwaysSucceed ,
10
+ MockValidatorsFailingOnBlockBodies ,
11
+ MockValidatorsFailOnSpecificBlockNumber
12
+ }
9
13
import io .iohk .ethereum .BlockHelpers
10
14
import io .iohk .ethereum .Fixtures .{Blocks => FixtureBlocks }
11
15
import io .iohk .ethereum .blockchain .sync .PeersClient .BlacklistPeer
@@ -151,6 +155,69 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
151
155
peersClient.expectMsgClass(classOf [BlacklistPeer ])
152
156
peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest => () }
153
157
}
158
+
159
+ " should be able to handle block bodies received in several parts" in new TestSetup {
160
+
161
+ startFetcher()
162
+
163
+ val getBlockHeadersRequest =
164
+ GetBlockHeaders (Left (1 ), syncConfig.blockHeadersPerRequest, skip = 0 , reverse = false )
165
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockHeadersRequest => () }
166
+
167
+ val chain = BlockHelpers .generateChain(syncConfig.blockHeadersPerRequest, FixtureBlocks .Genesis .block)
168
+
169
+ val getBlockHeadersResponse = BlockHeaders (chain.map(_.header))
170
+ peersClient.reply(PeersClient .Response (fakePeer, getBlockHeadersResponse))
171
+
172
+ val getBlockBodiesRequest1 = GetBlockBodies (chain.map(_.hash))
173
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest1 => () }
174
+
175
+ // It will receive all the requested bodies, but splitted in 2 parts.
176
+ val (subChain1, subChain2) = chain.splitAt(syncConfig.blockHeadersPerRequest / 2 )
177
+
178
+ val getBlockBodiesResponse1 = BlockBodies (subChain1.map(_.body))
179
+ peersClient.reply(PeersClient .Response (fakePeer, getBlockBodiesResponse1))
180
+
181
+ val getBlockHeadersRequest2 =
182
+ GetBlockHeaders (Left (subChain1.last.number + 1 ), syncConfig.blockHeadersPerRequest, skip = 0 , reverse = false )
183
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockHeadersRequest2 => () }
184
+
185
+ val getBlockBodiesRequest2 = GetBlockBodies (subChain2.map(_.hash))
186
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest2 => () }
187
+
188
+ val getBlockBodiesResponse2 = BlockBodies (subChain2.map(_.body))
189
+ peersClient.reply(PeersClient .Response (fakePeer, getBlockBodiesResponse2))
190
+
191
+ peersClient.expectNoMessage()
192
+ }
193
+
194
+ " should ignore response, without blacklist the peer, in case a sub ordered block bodies chain is received" in new TestSetup {
195
+
196
+ // Important: Here (in a hacky way) we are enforcing received bodies
197
+ // to be a sub ordered chain that fetcher can't append given their current state
198
+ override lazy val validators = new MockValidatorsFailOnSpecificBlockNumber (1 )
199
+
200
+ startFetcher()
201
+
202
+ val getBlockHeadersRequest =
203
+ GetBlockHeaders (Left (1 ), syncConfig.blockHeadersPerRequest, skip = 0 , reverse = false )
204
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockHeadersRequest => () }
205
+
206
+ val chain = BlockHelpers .generateChain(syncConfig.blockHeadersPerRequest, FixtureBlocks .Genesis .block)
207
+
208
+ val getBlockHeadersResponse = BlockHeaders (chain.map(_.header))
209
+ peersClient.reply(PeersClient .Response (fakePeer, getBlockHeadersResponse))
210
+
211
+ val getBlockBodiesRequest1 = GetBlockBodies (chain.map(_.hash))
212
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest1 => () }
213
+
214
+ val (subChain1, _) = chain.splitAt(syncConfig.blockHeadersPerRequest / 2 )
215
+
216
+ val getBlockBodiesResponse1 = BlockBodies (subChain1.map(_.body))
217
+ peersClient.reply(PeersClient .Response (fakePeer, getBlockBodiesResponse1))
218
+
219
+ peersClient.expectMsgPF() { case PeersClient .Request (msg, _, _) if msg == getBlockBodiesRequest1 => () }
220
+ }
154
221
}
155
222
156
223
trait TestSetup extends TestSyncConfig {
0 commit comments