Skip to content

Commit 5a91450

Browse files
committed
[ETCM-283] Fix and Refactor tests
1 parent 397d0bd commit 5a91450

File tree

4 files changed

+49
-36
lines changed

4 files changed

+49
-36
lines changed

src/it/scala/io/iohk/ethereum/sync/util/RegularSyncItSpecUtils.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package io.iohk.ethereum.sync.util
33
import akka.actor.ActorRef
44
import akka.util.ByteString
55
import cats.effect.Resource
6-
import io.iohk.ethereum.Mocks.MockValidatorsAlwaysSucceed
76
import io.iohk.ethereum.blockchain.sync.{PeersClient, SyncProtocol}
87
import io.iohk.ethereum.blockchain.sync.regular.BlockBroadcasterActor.BroadcastBlock
98
import io.iohk.ethereum.blockchain.sync.regular.RegularSync
@@ -63,7 +62,7 @@ object RegularSyncItSpecUtils {
6362
"pending-transactions-manager"
6463
)
6564

66-
lazy val validators = new MockValidatorsAlwaysSucceed
65+
lazy val validators = buildEthashConsensus.validators
6766

6867
lazy val regularSync = system.actorOf(
6968
RegularSync.props(

src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcherState.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ case class BlockFetcherState(
148148
else
149149
bodiesAreOrderedSubsetOfRequested(remainingHeaders, respondedBodies, matchedBlocks)
150150
}
151-
151+
152152
/**
153153
* If blocks is empty collection - headers in queue are removed as the cause is:
154154
* - the headers are from rejected fork and therefore it won't be possible to resolve blocks for them
@@ -161,7 +161,6 @@ case class BlockFetcherState(
161161
waitingHeaders = Queue.empty
162162
)
163163
else
164-
// We could optimize this by stopping as soon as a block is not enqueued.
165164
blocks.foldLeft(this) { case (state, block) =>
166165
state.enqueueRequestedBlock(block, fromPeer)
167166
}
@@ -174,7 +173,7 @@ case class BlockFetcherState(
174173
waitingHeaders.dequeueOption
175174
.map { case (waitingHeader, waitingHeadersTail) =>
176175
if (waitingHeader.hash == block.hash)
177-
withPeerForBlocks(fromPeer, Seq(block.header.number))
176+
withPeerForBlocks(fromPeer, Seq(block.number))
178177
.withPossibleNewTopAt(block.number)
179178
.withLastBlock(block.number)
180179
.copy(

src/test/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcherSpec.scala

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ import java.net.InetSocketAddress
44
import akka.actor.ActorSystem
55
import akka.testkit.{TestKit, TestProbe}
66
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}
128
import io.iohk.ethereum.BlockHelpers
139
import io.iohk.ethereum.Fixtures.{Blocks => FixtureBlocks}
1410
import io.iohk.ethereum.blockchain.sync.PeersClient.BlacklistPeer
@@ -129,7 +125,7 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
129125
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == firstGetBlockHeadersRequest => () }
130126
}
131127

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 {
133129

134130
// Important: Here we are forcing the mismatch between request headers and received bodies
135131
override lazy val validators = new MockValidatorsFailingOnBlockBodies
@@ -151,6 +147,7 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
151147
val getBlockBodiesResponse = BlockBodies(chain.map(_.body))
152148
peersClient.reply(PeersClient.Response(fakePeer, getBlockBodiesResponse))
153149

150+
// Fetcher should blacklist the peer and retry asking for the same bodies
154151
peersClient.expectMsgClass(classOf[BlacklistPeer])
155152
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockBodiesRequest => () }
156153
}
@@ -172,13 +169,13 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
172169
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockBodiesRequest1 => () }
173170

174171
// It will receive all the requested bodies, but splitted in 2 parts.
175-
val (subChain1, subChain2) = chain.splitAt(syncConfig.blockHeadersPerRequest / 2)
172+
val (subChain1, subChain2) = chain.splitAt(syncConfig.blockBodiesPerRequest / 2)
176173

177174
val getBlockBodiesResponse1 = BlockBodies(subChain1.map(_.body))
178175
peersClient.reply(PeersClient.Response(fakePeer, getBlockBodiesResponse1))
179176

180177
val getBlockHeadersRequest2 =
181-
GetBlockHeaders(Left(subChain1.last.number + 1), syncConfig.blockHeadersPerRequest, skip = 0, reverse = false)
178+
GetBlockHeaders(Left(chain.last.number + 1), syncConfig.blockHeadersPerRequest, skip = 0, reverse = false)
182179
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockHeadersRequest2 => () }
183180

184181
val getBlockBodiesRequest2 = GetBlockBodies(subChain2.map(_.hash))
@@ -188,13 +185,15 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
188185
peersClient.reply(PeersClient.Response(fakePeer, getBlockBodiesResponse2))
189186

190187
peersClient.expectNoMessage()
191-
}
192188

193-
"should ignore response, without blacklist the peer, in case a sub ordered block bodies chain is received" in new TestSetup {
189+
importer.send(blockFetcher, PickBlocks(chain.size))
190+
importer.ignoreMsg({ case BlockImporter.NotOnTop => true })
191+
importer.expectMsgPF() { case BlockFetcher.PickedBlocks(blocks) =>
192+
blocks.map(_.hash).toList shouldEqual chain.map(_.hash)
193+
}
194+
}
194195

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)
196+
"should stop requesting, without blacklist the peer, in case empty bodies are received" in new TestSetup {
198197

199198
startFetcher()
200199

@@ -210,12 +209,31 @@ class BlockFetcherSpec extends TestKit(ActorSystem("BlockFetcherSpec_System")) w
210209
val getBlockBodiesRequest1 = GetBlockBodies(chain.map(_.hash))
211210
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockBodiesRequest1 => () }
212211

213-
val (subChain1, _) = chain.splitAt(syncConfig.blockHeadersPerRequest / 2)
212+
// It will receive part of the requested bodies.
213+
val (subChain1, subChain2) = chain.splitAt(syncConfig.blockBodiesPerRequest / 2)
214214

215215
val getBlockBodiesResponse1 = BlockBodies(subChain1.map(_.body))
216216
peersClient.reply(PeersClient.Response(fakePeer, getBlockBodiesResponse1))
217217

218-
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockBodiesRequest1 => () }
218+
val getBlockHeadersRequest2 =
219+
GetBlockHeaders(Left(chain.last.number + 1), syncConfig.blockHeadersPerRequest, skip = 0, reverse = false)
220+
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockHeadersRequest2 => () }
221+
222+
val getBlockBodiesRequest2 = GetBlockBodies(subChain2.map(_.hash))
223+
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockBodiesRequest2 => () }
224+
225+
// We receive empty bodies instead of the second part
226+
val getBlockBodiesResponse2 = BlockBodies(List())
227+
peersClient.reply(PeersClient.Response(fakePeer, getBlockBodiesResponse2))
228+
229+
peersClient.expectNoMessage()
230+
231+
// If we try to pick the whole chain we should only receive the first part
232+
importer.send(blockFetcher, PickBlocks(chain.size))
233+
importer.ignoreMsg({ case BlockImporter.NotOnTop => true })
234+
importer.expectMsgPF() { case BlockFetcher.PickedBlocks(blocks) =>
235+
blocks.map(_.hash).toList shouldEqual subChain1.map(_.hash)
236+
}
219237
}
220238

221239
"should ensure blocks passed to importer are always forming chain" in new TestSetup {

src/test/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcherStateSpec.scala

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ package io.iohk.ethereum.blockchain.sync.regular
33
import akka.actor.ActorSystem
44
import akka.testkit.{TestKit, TestProbe}
55
import io.iohk.ethereum.Mocks.MockValidatorsAlwaysSucceed
6-
import io.iohk.ethereum.domain.Block
76
import io.iohk.ethereum.BlockHelpers
8-
import io.iohk.ethereum.Fixtures.Blocks.ValidBlock
9-
import io.iohk.ethereum.domain.Block
107
import io.iohk.ethereum.network.PeerId
118
import org.scalatest.matchers.should.Matchers
129
import org.scalatest.wordspec.AnyWordSpecLike
@@ -30,35 +27,35 @@ class BlockFetcherStateSpec extends TestKit(ActorSystem()) with AnyWordSpecLike
3027

3128
"handling requested blocks" should {
3229
"clear headers queue if got empty list of blocks" in {
30+
val importer = TestProbe().ref
3331
val headers = BlockHelpers.generateChain(5, BlockHelpers.genesis).map(_.header)
3432
val peer = PeerId("foo")
3533

3634
val result = BlockFetcherState
37-
.initial(TestProbe().ref, 0)
35+
.initial(importer, validators.blockValidator, 0)
3836
.appendHeaders(headers)
39-
.map(_.handleRequestedBlocks(peer, List()))
40-
.map(_.waitingHeaders)
37+
.map(_.handleRequestedBlocks(List(), peer))
4138

42-
assert(result === Right(Queue.empty))
43-
result.lastBlock shouldEqual 0
39+
assert(result.map(_.waitingHeaders) === Right(Queue.empty))
40+
assert(result.map(_.lastBlock) === Right(headers.last.number))
4441
}
4542

4643
"enqueue requested blocks" in {
47-
44+
val importer = TestProbe().ref
4845
val blocks = BlockHelpers.generateChain(5, BlockHelpers.genesis)
4946
val peer = PeerId("foo")
5047

5148
val result = BlockFetcherState
52-
.initial(TestProbe().ref, 0)
49+
.initial(importer, validators.blockValidator, 0)
5350
.appendHeaders(blocks.map(_.header))
54-
.map(_.handleRequestedBlocks(peer, blocks.map(_.body)))
51+
.map(_.handleRequestedBlocks(blocks, peer))
5552

56-
assert(result.waitingHeaders === Right(Queue.empty))
57-
result.lastBlock shouldEqual blocks.lastBlock.number
58-
blocks.forEach { block =>
59-
result.blockProviders(block.number) shouldEqual fakePeerId
53+
assert(result.map(_.waitingHeaders) === Right(Queue.empty))
54+
assert(result.map(_.lastBlock) === Right(blocks.last.number))
55+
blocks.foreach { block =>
56+
assert(result.map(_.blockProviders(block.number)) === Right(peer))
6057
}
61-
result.knownTop shouldEqual blocks.lastBlock.number
58+
assert(result.map(_.knownTop) === Right(blocks.last.number))
6259
}
6360
}
6461
}

0 commit comments

Comments
 (0)