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

internal/ethapi: quantity-encode storage keys in eth_getProof response #27309

Merged
merged 9 commits into from
Jun 21, 2023

Conversation

prestwich
Copy link
Contributor

@prestwich prestwich commented May 19, 2023

Closes #27306

I am not completely familiar with the json marshalling system. I've tried to pattern match on other code, but may have gotten something wrong

@vinioleg2015zem vinioleg2015zem linked an issue May 21, 2023 that may be closed by this pull request
Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

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

LGTM

@holiman holiman changed the title fix: quantity-encode storage keys in eth_getProof responses internal/ethapi: quantity-encode storage keys in eth_getProof response May 21, 2023
@prestwich
Copy link
Contributor Author

Updated the test to match the changed encoding. Note that I believe this will impact hive RPC compatibility tests (given the changed RPC output). But given that this is a more-strict encoding of the same data, it should not impact any properly implement RPC clients

@@ -680,6 +680,7 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
// create the proof for the storageKeys
for i, hexKey := range storageKeys {
key, err := decodeHash(hexKey)
keyInt := (*hexutil.Big)(new(big.Int).SetBytes(key[:]))
Copy link
Contributor

Choose a reason for hiding this comment

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

It's a bit unorthodox to do this operation, involving key, before checking/handling the err. It's safe, in this instance, but not "The Way" :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

my go is far from idiomatic

@holiman
Copy link
Contributor

holiman commented Jun 6, 2023

Having thought about this one some more, I have somewhat changed my stance. Originally, I thought that there was no reason to ever return non-canonical keys, period. If user submits some "invalid" 0x0dead, then we should still return 0xdead.

And for that particular case, I still think so. However, there's another situation that can happen too, which is when the user expects the input/output to be 32-byte hashes, fully prefixed by zeroes. As we have it right now, the user can submit keys as 32-byte hashes, and obtain response proofs containing 32-byte hashes.

So right now, our API isn't opinionated, it allows either type. I think this is kind of neat, with the only drawback that it also allows totally off-standard fomats like 0x000dead.

One way to handle this would be to check they key it is "hash" (full 32-byte zero-prefixed),

  • and if so: return as is,
  • and if not: do what this PR does and trim left.

@prestwich
Copy link
Contributor Author

So the new behavior becomes

  • if the input storage key conforms to hash32 then the output storage key conforms to hash32
  • otherwise, the output storage key conforms to quantity

This means that correctly-formatted output cannot be identified with a regex, without knowing the input length, which seems like a wart in the specification (which uses regex definitions)

@fjl
Copy link
Contributor

fjl commented Jun 6, 2023

I think @holiman did not mean the specification should be changed. The spec says it's a quantity and it should remain one. He just wants to preserve the current behavior for people calling this API method with 32-byte inputs. It makes sense, sort of.

@fjl
Copy link
Contributor

fjl commented Jun 20, 2023

Should be done now. @holiman PTAL.

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

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

LGTM!

@fjl fjl merged commit fd5d2ef into ethereum:master Jun 21, 2023
@fjl fjl added this to the 1.12.1 milestone Jun 21, 2023
devopsbo3 pushed a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
ethereum#27309)

This changes the eth_getProof method implementation to re-encode the requested
storage keys, canonicalizing them in the response. For backwards-compatibility reasons,
go-ethereum accepts non-canonical hex keys. Accepting them is fine, but we should
not mirror invalid inputs into the output.

Closes ethereum#27306

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Felix Lange <fjl@twurst.com>
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

eth_getProof implementation does not conform to EIP-1186 > content://media/external/downloads/1000000694
3 participants