Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[ETCM-283] Add block bodies validation in block fetcher #771

Merged
merged 14 commits into from
Nov 24, 2020

Conversation

mirkoAlic
Copy link
Contributor

@mirkoAlic mirkoAlic commented Nov 3, 2020

Description

Our current BlockFetcher doesn't do any validation on the BlockHeaders and BlockBodies messages received and just match them.

Proposed solution

Validate the matching between new bodies received and expected headers, if there isn't a match fetcher will complain about the peer that send those bodies.

Important Changes Introduced

blockchain.sync.regular.BlockFetcherState now is coupled to consensus.validators.std.StdBlockValidator
^ Ideally we shouldn't do such thing!

TODO

add test regarding a sub ordered sequence of bodies received

@mirkoAlic mirkoAlic marked this pull request as ready for review November 4, 2020 17:45
@mirkoAlic mirkoAlic added the WIP label Nov 13, 2020
@mirkoAlic mirkoAlic force-pushed the etcm-283-validate-bodies-in-block-fetcher branch from 640d8c5 to 21d65f8 Compare November 17, 2020 15:28
@mirkoAlic mirkoAlic removed the WIP label Nov 17, 2020
kapke
kapke previously approved these changes Nov 18, 2020
Copy link
Contributor

@kapke kapke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests need a bit more comments, besides that the code looks good to me!

@@ -71,6 +73,7 @@ object RegularSyncItSpecUtils {
ledger,
bl,
blockchainConfig, // FIXME: remove in ETCM-280
validators.blockValidator,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: should this validator be used here instead of more close to production one?

peersClient.reply(PeersClient.Response(fakePeer, getBlockBodiesResponse))

peersClient.expectMsgClass(classOf[BlacklistPeer])
peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockBodiesRequest => () }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about test like:

  • fetch one batch of blocks
  • for the second batch send different bodies (so even proper validator fails)
  • pick blocks and verify that only these from first batch are responded

Basically same issue with these tests - lack of explicit assertions or at least comments, why it's enough to check for certain message/lack of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main issue i see with the test you propose is that i would need the real block validator, and that make things more complex. So i will opt for improve current test assertions if you are ok with that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(main issue is current impl of bodiesAreOrderedSubsetOfRequested, given i can't use a simple mock validator to match headers and bodies)

peersClient.expectMsgPF() { case PeersClient.Request(msg, _, _) if msg == getBlockBodiesRequest1 => () }

// It will receive all the requested bodies, but splitted in 2 parts.
val (subChain1, subChain2) = chain.splitAt(syncConfig.blockHeadersPerRequest / 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

block bodies per request? I know these are same values in tests, but the right config value should be used anyway I think

val getBlockBodiesResponse2 = BlockBodies(subChain2.map(_.body))
peersClient.reply(PeersClient.Response(fakePeer, getBlockBodiesResponse2))

peersClient.expectNoMessage()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better way? Maybe try to pick blocks or sth like that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this expectNoMessageCall be removed now?

@kapke kapke self-requested a review November 18, 2020 14:12
@kapke kapke dismissed their stale review November 18, 2020 14:13

The approval, I'd like the tests to be a bit more polished ;)

@mirkoAlic
Copy link
Contributor Author

@kapke i will wait til your pr #787 is merged in order to polish the tests and adjust my code, given there will be some little overlapping between: addBodies <-> receiveBlocks.

Merge branch 'develop' of github.com:input-output-hk/mantis into etcm-283-validate-bodies-in-block-fetcher

Conflicts:
	src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcher.scala
	src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcherState.scala
	src/test/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcherSpec.scala
	src/test/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcherStateSpec.scala
@mirkoAlic mirkoAlic force-pushed the etcm-283-validate-bodies-in-block-fetcher branch 3 times, most recently from 5a91450 to 5c1fecd Compare November 19, 2020 20:16
@mirkoAlic mirkoAlic force-pushed the etcm-283-validate-bodies-in-block-fetcher branch from 5c1fecd to 0a4b94a Compare November 19, 2020 20:24
…s into etcm-283-validate-bodies-in-block-fetcher

Conflicts:
	src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockFetcher.scala
Copy link
Contributor

@kapke kapke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests look much better now!

val getBlockBodiesResponse2 = BlockBodies(subChain2.map(_.body))
peersClient.reply(PeersClient.Response(fakePeer, getBlockBodiesResponse2))

peersClient.expectNoMessage()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this expectNoMessageCall be removed now?

@mirkoAlic mirkoAlic merged commit b5cb34b into develop Nov 24, 2020
@mirkoAlic mirkoAlic deleted the etcm-283-validate-bodies-in-block-fetcher branch November 24, 2020 13:07
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants