Skip to content

Commit 932853b

Browse files
author
Leonor Boga
committed
[ETCM-709] Improve ommers validations
Replaced OmmersAncestorsError by more specific OmmerIsAncestorError and OmmerParentIsNotAncestorError. Renamed OmmersNotValidError to OmmersHeaderError and added the underlying reason for failure Refactored validateOmmersAncestors method. Refactored validateOmmersHeaders method to not hide the underlying failing reason. Reorganized some packages because some classes were not in the correct package and/or the Spec was not in the correct package. Renamed some specs to better reflect the class being tested Raised the log level of some logs in BlockFetcher because there are barely any logs this actor when debug logs are disabled
1 parent 23534aa commit 932853b

28 files changed

+213
-120
lines changed

src/ets/scala/io/iohk/ethereum/ets/blockchain/BlockchainTestConfig.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package io.iohk.ethereum.ets.blockchain
22

33
import akka.util.ByteString
44
import io.iohk.ethereum.consensus.Protocol
5-
import io.iohk.ethereum.consensus.ethash.validators.ValidatorsExecutor
5+
import io.iohk.ethereum.consensus.validators.std.ValidatorsExecutor
66
import io.iohk.ethereum.domain.{Address, UInt256}
77
import io.iohk.ethereum.utils.{BlockchainConfig, DaoForkConfig, MonetaryPolicyConfig}
88
import org.bouncycastle.util.encoders.Hex

src/ets/scala/io/iohk/ethereum/ets/blockchain/ScenarioSetup.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package io.iohk.ethereum.ets.blockchain
33
import akka.util.ByteString
44
import io.iohk.ethereum.consensus.Protocol.NoAdditionalEthashData
55
import io.iohk.ethereum.consensus.ethash.EthashConsensus
6-
import io.iohk.ethereum.consensus.ethash.validators.ValidatorsExecutor
6+
import io.iohk.ethereum.consensus.validators.std.ValidatorsExecutor
77
import io.iohk.ethereum.consensus.{ConsensusConfig, FullConsensusConfig, TestConsensus, ethash}
88
import io.iohk.ethereum.db.components.Storages.PruningModeComponent
99
import io.iohk.ethereum.db.components.{EphemDataSourceComponent, Storages}
@@ -18,6 +18,7 @@ import io.iohk.ethereum.utils.BigIntExtensionMethods._
1818
import io.iohk.ethereum.utils.{BlockchainConfig, Config}
1919
import monix.execution.Scheduler
2020
import org.bouncycastle.util.encoders.Hex
21+
2122
import scala.util.{Failure, Success, Try}
2223

2324
object ScenarioSetup {

src/it/scala/io/iohk/ethereum/sync/RegularSyncItSpec.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,12 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl
152152
_ <- peer1.waitForRegularSyncLoadLastBlock(length)
153153
} yield {
154154
assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash)
155-
assert(peer1.bl.getBestBlock().get.number == peer2.bl.getBestBlock().get.number && peer1.bl.getBestBlock().get.number == length)
155+
assert(
156+
peer1.bl.getBestBlock().get.number == peer2.bl.getBestBlock().get.number && peer1.bl
157+
.getBestBlock()
158+
.get
159+
.number == length
160+
)
156161
assert(peer1.bl.getLatestCheckpointBlockNumber() == peer2.bl.getLatestCheckpointBlockNumber())
157162
}
158163
}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ import io.iohk.ethereum.Mocks.MockValidatorsAlwaysSucceed
77
import io.iohk.ethereum.blockchain.sync.regular.BlockBroadcast.BlockToBroadcast
88
import io.iohk.ethereum.blockchain.sync.regular.BlockBroadcasterActor.BroadcastBlock
99
import io.iohk.ethereum.blockchain.sync.regular.BlockImporter.Start
10-
import io.iohk.ethereum.blockchain.sync.regular.{BlockBroadcast, BlockBroadcasterActor, BlockFetcher, BlockImporter, RegularSync}
10+
import io.iohk.ethereum.blockchain.sync.regular.{
11+
BlockBroadcast,
12+
BlockBroadcasterActor,
13+
BlockFetcher,
14+
BlockImporter,
15+
RegularSync
16+
}
1117
import io.iohk.ethereum.blockchain.sync.regular.RegularSync.NewCheckpoint
1218
import io.iohk.ethereum.blockchain.sync.{PeersClient, SyncProtocol}
1319
import io.iohk.ethereum.checkpointing.CheckpointingTestHelpers
@@ -97,7 +103,8 @@ object RegularSyncItSpecUtils {
97103
pendingTransactionsManager,
98104
checkpointBlockGenerator,
99105
regularSync
100-
))
106+
)
107+
)
101108

102109
lazy val regularSync = system.actorOf(
103110
RegularSync.props(

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

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class BlockFetcher(
9898

9999
private def handleCommands(state: BlockFetcherState): Receive = {
100100
case PickBlocks(amount) => state.pickBlocks(amount) |> handlePickedBlocks(state) |> fetchBlocks
101+
101102
case StrictPickBlocks(from, atLeastWith) =>
102103
// FIXME: Consider having StrictPickBlocks calls guaranteeing this
103104
// from parameter could be negative or 0 so we should cap it to 1 if that's the case
@@ -113,9 +114,10 @@ class BlockFetcher(
113114
}
114115

115116
fetchBlocks(newState)
117+
116118
case InvalidateBlocksFrom(blockNr, reason, withBlacklist) =>
117119
val (blockProvider, newState) = state.invalidateBlocksFrom(blockNr, withBlacklist)
118-
log.debug("Invalidate blocks from {}", blockNr)
120+
log.info("Invalidate blocks from {}", blockNr)
119121
blockProvider.foreach(peersClient ! BlacklistPeer(_, reason))
120122
fetchBlocks(newState)
121123
}
@@ -124,7 +126,7 @@ class BlockFetcher(
124126
case Response(_, BlockHeaders(headers)) if state.isFetchingHeaders =>
125127
val newState =
126128
if (state.fetchingHeadersState == AwaitingHeadersToBeIgnored) {
127-
log.debug(
129+
log.info(
128130
"Received {} headers starting from block {} that will be ignored",
129131
headers.size,
130132
headers.headOption.map(_.number)
@@ -149,17 +151,17 @@ class BlockFetcher(
149151

150152
fetchBlocks(newState)
151153
case RetryHeadersRequest if state.isFetchingHeaders =>
152-
log.debug("Something failed on a headers request, cancelling the request and re-fetching")
154+
log.info("Something failed on a headers request, cancelling the request and re-fetching")
153155

154156
val newState = state.withHeaderFetchReceived
155157
fetchBlocks(newState)
156158
}
157159

158160
private def handleBodiesMessages(state: BlockFetcherState): Receive = {
159161
case Response(peer, BlockBodies(bodies)) if state.isFetchingBodies =>
160-
log.debug(s"Received ${bodies.size} block bodies")
162+
log.debug("Received {} block bodies", bodies.size)
161163
if (state.fetchingBodiesState == AwaitingBodiesToBeIgnored) {
162-
log.debug("Block bodies will be ignored due to an invalidation was requested for them")
164+
log.info("Block bodies will be ignored due to an invalidation was requested for them")
163165
fetchBlocks(state.withBodiesFetchReceived)
164166
} else {
165167
val newState =
@@ -171,19 +173,22 @@ class BlockFetcher(
171173
state.withBodiesFetchReceived.handleRequestedBlocks(newBlocks, peer.id)
172174
}
173175
val waitingHeadersDequeued = state.waitingHeaders.size - newState.waitingHeaders.size
174-
log.debug(s"Processed $waitingHeadersDequeued new blocks from received block bodies")
176+
log.debug("Processed {} new blocks from received block bodies", waitingHeadersDequeued)
175177
fetchBlocks(newState)
176178
}
179+
177180
case RetryBodiesRequest if state.isFetchingBodies =>
178-
log.debug("Something failed on a bodies request, cancelling the request and re-fetching")
181+
log.info("Something failed on a bodies request, cancelling the request and re-fetching")
179182
val newState = state.withBodiesFetchReceived
180183
fetchBlocks(newState)
181184
}
182185

183186
private def handleStateNodeMessages(state: BlockFetcherState): Receive = {
184187
case FetchStateNode(hash) => fetchStateNode(hash, sender(), state)
188+
185189
case RetryFetchStateNode if state.isFetchingStateNode =>
186190
state.stateNodeFetcher.foreach(fetcher => fetchStateNode(fetcher.hash, fetcher.replyTo, state))
191+
187192
case Response(peer, NodeData(values)) if state.isFetchingStateNode =>
188193
log.debug("Received state node response from peer {}", peer)
189194
state.stateNodeFetcher.foreach(fetcher => {
@@ -196,7 +201,7 @@ class BlockFetcher(
196201

197202
validatedNode match {
198203
case Left(err) =>
199-
log.debug(err)
204+
log.info(err)
200205
peersClient ! BlacklistPeer(peer.id, err)
201206
fetchStateNode(fetcher.hash, fetcher.replyTo, state)
202207
case Right(node) =>
@@ -215,10 +220,13 @@ class BlockFetcher(
215220
}
216221
supervisor ! ProgressProtocol.GotNewBlock(newState.knownTop)
217222
fetchBlocks(newState)
223+
218224
case MessageFromPeer(CommonMessages.NewBlock(block, _), peerId) =>
219225
handleNewBlock(block, peerId, state)
226+
220227
case MessageFromPeer(PV64.NewBlock(block, _), peerId) =>
221228
handleNewBlock(block, peerId, state)
229+
222230
case BlockImportFailed(blockNr, reason) =>
223231
val (peerId, newState) = state.invalidateBlocksFrom(blockNr)
224232
peerId.foreach(id => peersClient ! BlacklistPeer(id, reason))
@@ -247,7 +255,7 @@ class BlockFetcher(
247255
}
248256

249257
private def handleFutureBlock(block: Block, state: BlockFetcherState): Unit = {
250-
log.debug("Ignoring received block as it doesn't match local state or fetch side is not on top")
258+
log.info("Ignoring received block as it doesn't match local state or fetch side is not on top")
251259
val newState = state.withPossibleNewTopAt(block.number)
252260
supervisor ! ProgressProtocol.GotNewBlock(newState.knownTop)
253261
fetchBlocks(newState)
@@ -259,16 +267,18 @@ class BlockFetcher(
259267
state.tryInsertBlock(block, peerId) match {
260268
case Left(_) if block.number <= state.lastBlock =>
261269
log.debug(
262-
s"Checkpoint block ${ByteStringUtils.hash2string(blockHash)} is older than current last block ${state.lastBlock}" +
263-
s" - clearing the queues and putting checkpoint to ready blocks queue"
270+
"Checkpoint block {} is older than current last block {} - clearing the queues and putting checkpoint to ready blocks queue",
271+
ByteStringUtils.hash2string(blockHash),
272+
state.lastBlock
264273
)
265274
val newState = state
266275
.clearQueues()
267276
.enqueueReadyBlock(block, peerId)
268277
fetchBlocks(newState)
269278
case Left(_) if block.number <= state.knownTop =>
270279
log.debug(
271-
s"Checkpoint block ${ByteStringUtils.hash2string(blockHash)} not fit into queues - clearing the queues and setting possible new top"
280+
"Checkpoint block {} not fit into queues - clearing the queues and setting possible new top",
281+
ByteStringUtils.hash2string(blockHash)
272282
)
273283
val newState = state
274284
.clearQueues()
@@ -279,7 +289,7 @@ class BlockFetcher(
279289
log.debug(error)
280290
handleFutureBlock(block, state)
281291
case Right(state) =>
282-
log.debug(s"Checkpoint block [${ByteStringUtils.hash2string(blockHash)}] fit into queues")
292+
log.debug("Checkpoint block [{}] fit into queues", ByteStringUtils.hash2string(blockHash))
283293
fetchBlocks(state)
284294
}
285295
}
@@ -289,20 +299,20 @@ class BlockFetcher(
289299
//ex. After a successful handshake, fetcher will receive the info about the header of the peer best block
290300
case MessageFromPeer(BlockHeaders(headers), _) =>
291301
headers.lastOption.map { bh =>
292-
log.debug(s"Candidate for new top at block ${bh.number}, current known top ${state.knownTop}")
302+
log.info("Candidate for new top at block {}, current known top {}", bh.number, state.knownTop)
293303
val newState = state.withPossibleNewTopAt(bh.number)
294304
fetchBlocks(newState)
295305
}
296306
//keep fetcher state updated in case new mined block was imported
297307
case InternalLastBlockImport(blockNr) =>
298-
log.debug(s"New mined block $blockNr imported from the inside")
308+
log.info("New mined block {} imported from the inside", blockNr)
299309
val newState = state.withLastBlock(blockNr).withPossibleNewTopAt(blockNr)
300310

301311
fetchBlocks(newState)
302312

303313
//keep fetcher state updated in case new checkpoint block was imported
304314
case InternalCheckpointImport(blockNr) =>
305-
log.debug(s"New checkpoint block $blockNr imported from the inside")
315+
log.info("New checkpoint block {} imported from the inside", blockNr)
306316

307317
val newState = state
308318
.clearQueues()
@@ -414,13 +424,16 @@ class BlockFetcher(
414424

415425
private def handleRequestResult(fallback: FetchMsg)(msg: Any): Task[Any] = msg match {
416426
case failed: RequestFailed =>
417-
log.debug("Request failed due to {}", failed)
427+
log.error("Request failed due to {}", failed)
418428
Task.now(fallback)
429+
419430
case NoSuitablePeer =>
420431
Task.now(fallback).delayExecution(syncConfig.syncRetryInterval)
432+
421433
case Failure(cause) =>
422434
log.error(cause, "Unexpected error on the request result")
423435
Task.now(fallback)
436+
424437
case m =>
425438
Task.now(m)
426439
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import io.iohk.ethereum.utils.Config.SyncConfig
2222
import io.iohk.ethereum.utils.FunctorOps._
2323
import monix.eval.Task
2424
import monix.execution.Scheduler
25+
import org.bouncycastle.util.encoders.Hex
2526

2627
import scala.concurrent.duration._
2728

@@ -87,7 +88,7 @@ class BlockImporter(
8788
importCheckpointBlock(checkpointBlock, state)
8889

8990
case None =>
90-
log.error(s"Could not find parent (${ByteStringUtils.hash2string(parentHash)}) for new checkpoint block")
91+
log.error("Could not find parent ({}) for new checkpoint block", ByteStringUtils.hash2string(parentHash))
9192
}
9293
}
9394

@@ -205,7 +206,12 @@ class BlockImporter(
205206
tryImportBlocks(restOfBlocks, importedBlocks)
206207

207208
case err @ (UnknownParent | BlockImportFailed(_)) =>
208-
log.error("Block {} import failed", blocks.head.number)
209+
log.error(
210+
"Block {} import failed, with hash {} and parent hash {}",
211+
blocks.head.number,
212+
blocks.head.header.hashAsHexString,
213+
ByteStringUtils.hash2string(blocks.head.header.parentHash)
214+
)
209215
Task.now((importedBlocks, Some(err)))
210216
}
211217
.onErrorHandle {

src/main/scala/io/iohk/ethereum/consensus/ConsensusBuilder.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package io.iohk.ethereum.consensus
22

33
import io.iohk.ethereum.consensus.Protocol.{NoAdditionalEthashData, RestrictedEthashMinerData}
44
import io.iohk.ethereum.consensus.ethash.EthashConsensus
5-
import io.iohk.ethereum.consensus.ethash.validators.ValidatorsExecutor
5+
import io.iohk.ethereum.consensus.validators.std.ValidatorsExecutor
66
import io.iohk.ethereum.nodebuilder._
77
import io.iohk.ethereum.utils.{Config, Logger}
88

src/main/scala/io/iohk/ethereum/consensus/ethash/EthashConsensus.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ import io.iohk.ethereum.consensus.ethash.blocks.{
1313
EthashBlockGeneratorImpl,
1414
RestrictedEthashBlockGeneratorImpl
1515
}
16-
import io.iohk.ethereum.consensus.ethash.validators.ValidatorsExecutor
1716
import io.iohk.ethereum.consensus.validators.Validators
17+
import io.iohk.ethereum.consensus.validators.std.ValidatorsExecutor
1818
import io.iohk.ethereum.domain.BlockchainImpl
1919
import io.iohk.ethereum.jsonrpc.AkkaTaskOps.TaskActorOps
2020
import io.iohk.ethereum.ledger.BlockPreparator
2121
import io.iohk.ethereum.ledger.Ledger.VMImpl
2222
import io.iohk.ethereum.nodebuilder.Node
2323
import io.iohk.ethereum.utils.{BlockchainConfig, Logger}
2424
import monix.eval.Task
25+
2526
import scala.concurrent.duration._
2627

2728
/**

src/main/scala/io/iohk/ethereum/consensus/ethash/blocks/EthashBlockGenerator.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import akka.util.ByteString
55
import io.iohk.ethereum.consensus.ConsensusConfig
66
import io.iohk.ethereum.consensus.blocks._
77
import io.iohk.ethereum.consensus.difficulty.DifficultyCalculator
8-
import io.iohk.ethereum.consensus.ethash.validators.ValidatorsExecutor
98
import io.iohk.ethereum.crypto.kec256
109
import io.iohk.ethereum.domain._
1110
import io.iohk.ethereum.ledger.{BlockPreparator, InMemoryWorldStateProxy}
1211
import io.iohk.ethereum.utils.BlockchainConfig
1312
import io.iohk.ethereum.consensus.ConsensusMetrics
13+
import io.iohk.ethereum.consensus.validators.std.ValidatorsExecutor
1414

1515
/** Internal API, used for testing (especially mocks) */
1616
trait EthashBlockGenerator extends TestBlockGenerator {

src/main/scala/io/iohk/ethereum/consensus/ethash/blocks/RestrictedEthashBlockGeneratorImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import io.iohk.ethereum.consensus.ConsensusConfig
44
import io.iohk.ethereum.consensus.blocks.{BlockTimestampProvider, DefaultBlockTimestampProvider, PendingBlockAndState}
55
import io.iohk.ethereum.consensus.difficulty.DifficultyCalculator
66
import io.iohk.ethereum.consensus.ethash.RestrictedEthashSigner
7-
import io.iohk.ethereum.consensus.ethash.validators.ValidatorsExecutor
87
import io.iohk.ethereum.domain.{Address, Block, Blockchain, SignedTransaction}
98
import io.iohk.ethereum.ledger.{BlockPreparator, InMemoryWorldStateProxy}
109
import io.iohk.ethereum.utils.BlockchainConfig
1110
import org.bouncycastle.crypto.AsymmetricCipherKeyPair
1211
import io.iohk.ethereum.consensus.ConsensusMetrics
12+
import io.iohk.ethereum.consensus.validators.std.ValidatorsExecutor
1313

1414
class RestrictedEthashBlockGeneratorImpl(
1515
validators: ValidatorsExecutor,

0 commit comments

Comments
 (0)