Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix blockchain tests #384

Merged
merged 1 commit into from
Nov 15, 2018
Merged

Fix blockchain tests #384

merged 1 commit into from
Nov 15, 2018

Conversation

mattdean-digicatapult
Copy link
Contributor

This fixes the last set of failing blockchain tests:

  • RPC_API_Test
  • randomStatetest224BC
  • randomStatetest234BC
  • randomStatetest529BC
  • ExtraData32
  • log1_correct
  • timeDiff0
  • timeDiff12
  • timeDiff13
  • timeDiff14

These were mostly caused by missing block validation and the intentional disparity between the bloom filter implementation and the yellow paper introduced in #295.

The bloom filter changes I've introduced are obviously problematic (hence do-not-merge) but without them the following additional test failures, caused by a lack of block validation, were being hidden:

  • DifferentExtraData1025
  • ExtraData1024
  • ExtraData33
  • wrongDifficulty
  • wrongGasLimit
  • wrongTimestamp
  • wrongTransactionsTrie
  • wrongUncleHash

These tests pass in master purely because the bloom filter does not match as expected rather than because block validation isn't occurring. I guess the obvious question is how do other implementations handle this disparity between the bloom filters when it comes to testing?

* @param {Buffer} buff
* @returns {Buffer} a slice of the given buffer starting at the first non-zero entry
*/
function dropLeadingZeroes (buff) {
Copy link
Member

Choose a reason for hiding this comment

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

This was introduced fairly recently (< 1 year ago). Can you please look up in git blame which PR introduced it and why? There was some reasoning.

Copy link
Member

Choose a reason for hiding this comment

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

Never mind, you've introduced it, nevertheless having the PR number linked here helps future tracking why things change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PR was #295

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As mentioned in my original comment I've only reverted this to demonstrate the scope of test failures this change has caused. This change has also caused other failures to be masked which raises the question as to the correct solution?

Copy link
Member

Choose a reason for hiding this comment

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

Hi @AusIV, the changes introduced in #295 resulted in a somewhat conflicting situation regarding passing of blockchain tests, see the thread in this issue. Have you got some deeper insight on this and can eventually join the discussion?

@coveralls
Copy link

coveralls commented Nov 7, 2018

Coverage Status

Coverage remained the same at 90.62% when pulling d21f06d on fix-blockchain-tests into a5480c2 on master.

@holgerd77
Copy link
Member

Short update: I did repository-wide searches on Parity Ethereum and go-ethereum searching for some of the test names mentioned above (e.g. to discover some skip list or similar), but didn't find anything matching.

@AusIV
Copy link
Contributor

AusIV commented Nov 8, 2018

Hey, I saw that you asked me to chime in about #295.

Several months ago I set out to ensure that Geth's RPC libraries could be used with Ganache, as I develop a Go application and wanted to use Ganache for testing. With that goal in mind, I made pull requests to a bunch of different dependencies of Ganache to ensure that things like block hashing and bloom filters were implemented to be compliant with the consensus clients.

In this case, the PR I made was because if I loaded a Ganache generated bloom filter into the Geth bloom filter library, and tested it for the topics that should have been present, it would return false, that those items were not present in the bloom filter. I eventually determined that this was because Geth (and other consensus clients) trim leading zeroes before hashing the values for insertion into the bloom filter.

When I made my PR seven months ago, the tests were passing. I was asked to make a few changes to style and naming conventions, but nothing that changed the behavior of my code.

It took a while for me to get to the requested changes, and I suspect that during that time new tests were created that copied the bloom filter that would have been incompatible with Geth and Parity into new tests.

After I made the requested stylistic changes, the tests on my branch were still passing, but I suspect the branch it got merged into was not compatible with the change.

I'm reasonably confident that my implementation of bloom filters is a correct (at least in the sense that it is compatible with the consensus clients). The failing tests were probably introduced between when my changes were made, and when my changes got merged.

@mattdean-digicatapult
Copy link
Contributor Author

Hi @AusIV, thanks for clarifying. I've just checked out your branch from your fork of the repo and indeed all the above tests do fail there as I would have expected. I think the issue is at the time we weren't running the blockchain tests as part of CI, we only ran the state tests, so this probably went by under the radar.

I think we need to do some investigation into how Geth and Parity deal with this discrepancy; I completely agree with your interpretation as to their bloom filter implementation BTW.

@holgerd77
Copy link
Member

Yes, that's correct, blockchain tests weren't running

@holgerd77
Copy link
Member

My current tendency is to leave implementation here as is, add the tests to the skipped list in tester.js and make it clear in the commenting there what the reasoning is.

Will also continue to think about if we can find a place for inter-client consensus discussions like this, since I am currently also a bit involved in coordination around ethereum/tests, it might be a way to establish consensus discussions directly there (as meta issues e.g.), let me know, if you have ideas on this or you know that there is already some initiative on this.

Long term solution would probably rather have an evolving up-to-date spec apart from the yellow paper. I know that there is some discussion around making K-EVM this up-to-date alternative/enhancing spec, not sure how far/concrete these discussions are. Maybe @cdetrio can say something on this, not sure?

@holgerd77
Copy link
Member

(so "as is" means, without this PR changes)

@mattdean-digicatapult
Copy link
Contributor Author

On further inspection of geth I'm not entirely convinced that they use the Add method referenced in #295 when constructing bloom filters. My go isn't very good but here goes:

The bloom filter is created on the block header here https://github.com/ethereum/go-ethereum/blob/c134e00e488bf4bfd88689ecf6b91ee351fb77e5/core/types/block.go#L197.
This enters their bloom filter creation code here https://github.com/ethereum/go-ethereum/blob/86a03f97d30c11a5321fa2f0fd37cbc4c7f63a32/core/types/bloom9.go#L94.
From there they are always using the Or method to compose bloom filters together. The topics are passed in as fixed length byte arrays (defined as the type common.Hash) and I don't see any casts to big.Int during this process.

Is there a potential inconsistency between using the Add method to compose bloom filters in the geth code and using the CreateBloom method?

@holgerd77
Copy link
Member

Hmm, maybe it would generally make sense to add some common bloom filter tests to the ethereum/tests repository? There aren't any, as far as I am aware?

@mattdean-digicatapult
Copy link
Contributor Author

@holgerd77, I'd actually say the ethereum/tests repo did a great job here. It produced failures exactly as intended, we just weren't running the tests so it was missed.

The issue in geth, if I'm correct (and that's a big if), would be that the Add method for constructing bloom filters just isn't used. I haven't dug into their tests to check any of this I may add. This also feels eerily similar to an issue in this repo a while back (#303) where we had an unused method that was broken in our bloom filter implementation.

@AusIV
Copy link
Contributor

AusIV commented Nov 13, 2018

I'm about ready to admit #295 may have been a mistake on my part, based on the assumption that Geth's bloom.Add() was used. In my own Go tests, I was using it to construct the bloom filter I was using for testing purposes.

But the other perplexing piece of this puzzle is that Geth's bloom.Test() and bloom.TestBytes() definitely do a conversion to big.Integer to test for membership in the bloom filter (see: https://github.com/ethereum/go-ethereum/blob/86a03f97d30c11a5321fa2f0fd37cbc4c7f63a32/core/types/bloom9.go#L76 ). This makes me think that none of bloom.Add(), bloom.Test(), and bloom.TestBytes() are actually used within Geth. Indeed, it appears that they have a separate module that does not depend on their Bloom implementation to handle filtering of logs: https://github.com/ethereum/go-ethereum/tree/9e24491c65120d3fb36da45e57a0cb87c549f621/core/bloombits

The other thing that confuses me is that my code uses bloom.Test() against mainnet blocks, and it seems like it works. I'll have to do some further investigation to see if it "working" might actually be the result of false positives in the bloom filter.

@AusIV
Copy link
Contributor

AusIV commented Nov 13, 2018

I've opened an issue with Geth, as I'm now convinced that the problem is in bloom.Add() and bloom.Test(). Sincere apologies for any confusion I've caused, #295 ought to be rolled back out.

@mattdean-digicatapult
Copy link
Contributor Author

Thanks @AusIV, to be honest I initially read the geth code exactly the same as you did. @holgerd77, first I'm going to rebase this and once that's done I think it's ready for review?

@holgerd77
Copy link
Member

@mattdean-digicatapult Yes, sounds great!

@AusIV Thank you very much for doing this deep-dive follow-up on this!

This fixes the last set of blockchain tests:

* RPC_API_Test
* randomStatetest224BC
* randomStatetest234BC
* randomStatetest529BC
* ExtraData32
* log1_correct
* timeDiff0
* timeDiff12
* timeDiff13
* timeDiff14

These were mostly caused by missing block validation and the intentional disparity between the bloom filter implementation and the yellow paper introduced in #295.
@holgerd77 holgerd77 force-pushed the fix-blockchain-tests branch from 4b08400 to d21f06d Compare November 15, 2018 12:23
@holgerd77
Copy link
Member

Rebased this.

Copy link
Member

@holgerd77 holgerd77 left a comment

Choose a reason for hiding this comment

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

Looks good, thanks guys for settling this out on such a fine-grained level!

@holgerd77 holgerd77 merged commit 7de7a5b into master Nov 15, 2018
@holgerd77 holgerd77 deleted the fix-blockchain-tests branch November 15, 2018 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants