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

VM: Strip zeros when putting contract storage in StateManager #880

Merged
merged 4 commits into from
Oct 7, 2020

Conversation

jochem-brouwer
Copy link
Member

@jochem-brouwer jochem-brouwer commented Sep 17, 2020

Closes #875

Had a bit of a wrong understanding here, storage slot values should be stripped of leading zeros, which is now enforced in putContractStorage. Since putting >32 bytes storage values is not possible in EVM, this is now also disallowed. If we strip leading zeros this means that any zero-byte will immediately be detected as "delete value", both in StateManager but also in MPT, which is nice.

@codecov
Copy link

codecov bot commented Sep 17, 2020

Codecov Report

❗ No coverage uploaded for pull request base (master@dd5f87d). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

Flag Coverage Δ
#account 92.85% <ø> (?)
#block 76.92% <ø> (?)
#blockchain 80.13% <ø> (?)
#common 93.19% <ø> (?)
#ethash 82.22% <ø> (?)
#tx 93.08% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

@jochem-brouwer
Copy link
Member Author

Right, tests are failing, but reading the errors seems like this is a case of "the tests are wrong". We might want to consider switching the tests to TypeScript at some point too, because looks like numbers get fed into putContractStorage where we expect Buffers. Will fix.

@holgerd77
Copy link
Member

@jochem-brouwer yes, that was exactly what I was thinking when reviewing #849 (switching to TypeScript), probably rather sooner than later since this should give direct benefits on reliability.

//cc @ryanio

throw new Error('Storage key cannot be longer than 32 bytes')
}

value = unpadBuffer(value)
Copy link
Member

Choose a reason for hiding this comment

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

You are writing in the comments that a value will be left-padded and then you actually unpad (I read the semantics of this function as: "remove the padding", correct me if I am wrong) here, how does this go together?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops this is a comment from when I was still thinking that storage slots should always be 32 bytes; this is thus not the case, the leading zeros are stripped. Will update

@jochem-brouwer jochem-brouwer changed the title VM: Enforce 32-bytes length when putting contract storage in StateManager VM: Strip zeros when putting contract storage in StateManager Sep 17, 2020
@ryanio
Copy link
Contributor

ryanio commented Sep 21, 2020

this LGTM! nice additional tests.

it just needs an update to ts now, then can approve and merge.

@jochem-brouwer jochem-brouwer force-pushed the storage-slots-32-bytes branch 3 times, most recently from 55a711a to ae8f63c Compare September 23, 2020 16:34
@jochem-brouwer
Copy link
Member Author

Rebased and updated the spelling/grammar errors in the docs, should be ready @ryanio 😄

@jochem-brouwer
Copy link
Member Author

jochem-brouwer commented Oct 1, 2020

Nvm should rebase

@holgerd77
Copy link
Member

@jochem-brouwer are you doing this "right now"? Otherwise should be also ok to use the "Update branch" function (rebase is a bit better of course) and I would do a review during the next hour or so.

@jochem-brouwer
Copy link
Member Author

jochem-brouwer commented Oct 1, 2020

Rebasing it now! @holgerd77

jochem-brouwer and others added 2 commits October 1, 2020 10:57
fix test; update comment

lint

fix test

fix grammar

Co-authored-by: Ryan Ghods <ryan@ryanio.com>

fix spelling

Co-authored-by: Ryan Ghods <ryan@ryanio.com>
@jochem-brouwer jochem-brouwer force-pushed the storage-slots-32-bytes branch from ae8f63c to 21e43e6 Compare October 1, 2020 08:58
@jochem-brouwer
Copy link
Member Author

jochem-brouwer commented Oct 1, 2020

This was an easy rebase, no conflicts 😄 Ready for review @holgerd77

I thought GitHub said there were conflicting files but doesn't seem to be.

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.

Some change requests on the comments, otherwise looks good. 😄

packages/vm/lib/state/stateManager.ts Outdated Show resolved Hide resolved
t.end()
})

it('should strip storage values lower than 32 bytes', async (t) => {
Copy link
Member

Choose a reason for hiding this comment

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

This test description is a bit misleading (stripping is logically not connected to the byte length) respectively also not correct (stripping is also done for 32-byte length. Can you please adjust?

Copy link
Member Author

Choose a reason for hiding this comment

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

I have edited this name in 5217f50, hope this is better. I think this name was from when I still expected storage values to always be 32 bytes and I did not edit it right when I realized that was wrong.

packages/vm/tests/api/state/stateManager.spec.ts Outdated Show resolved Hide resolved

await stateManager.putContractStorage(address, key0, value0)
const slot0 = await stateManager.getContractStorage(address, key0)
t.ok(slot0.equals(expect0), 'value of 31 bytes padded correctly')
Copy link
Member

Choose a reason for hiding this comment

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

Really nit, but I would think this test would be a bit better readable if the respective execution part of these two cases are combined with the value setup (so everything with *0 together and everything with *1 together)

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed -> 5217f50

Note: I have edited this test a little bit (it did unpadZeros in previous commits on this particular test, but none of the test cases actually had leading zeros)

@jochem-brouwer
Copy link
Member Author

Thanks for the review @holgerd77, had no time this afternoon to take a further look but have fixed (?) it now 😄

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.

Ok, this looks good now, thanks @jochem-brouwer, great find! Sorry that this took a bit long, will merge now.

@holgerd77 holgerd77 merged commit ff75130 into master Oct 7, 2020
@holgerd77 holgerd77 deleted the storage-slots-32-bytes branch October 7, 2020 10:06
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.

Check situation if a zero-Buffer is put into contract storage
3 participants