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

EIP-1702: Generalized Account Versioning Scheme #2

Open
sorpaas opened this issue Jan 15, 2019 · 20 comments
Open

EIP-1702: Generalized Account Versioning Scheme #2

sorpaas opened this issue Jan 15, 2019 · 20 comments

Comments

@sorpaas
Copy link
Owner

sorpaas commented Jan 15, 2019

Discussion thread for account versioning:

@nicksavers
Copy link

The format of this proposal is missing a few suggested paragraphs from the [eip-X.md](the https://github.com/ethereum/EIPs/blob/master/eip-X.md) template. Please go over that and add the paragraphs here possible.

@gumb0
Copy link

gumb0 commented Jun 14, 2019

If I understand Alternative Design correctly, it's only init code that has prefix, but not the deployed code. Maybe it's worth to clarify this.

Contract Execution
VM version used in contract execution is determined via calling address (I_a in yellow paper).

This sentence is not quite clear. Does it mean that it's determined by the version field of the executed contract? (I guess the edge case here is DELEGATECALL & CALLCODE, better to clarify which version is used, caller or callee)

@sorpaas
Copy link
Owner Author

sorpaas commented Jun 21, 2019

Does it mean that it's determined by the version field of the executed contract?

Yes. I used I_a in yellow paper to specify that. I think it covers the case for DELEGATECALL/CALLCODE. However, it's indeed debatable whether use another variable would be better (for example, use the version field of the code contract).

@sorpaas
Copy link
Owner Author

sorpaas commented Jun 21, 2019

A note regarding upgradable contract and account versioning (posted on Gitter as well) -- my current conclusion is that upgradable contracts are not affected at all by EIP-1702 variant 1 (or variant 2)!

  • If the contract uses the proxy contract pattern, it will not be affected. Deployment of the delegate contract happens through contract creation transaction, which deploys the latest VM version.
  • If the contract uses a CREATE opcode internally, then the owner can deploy an upgrade (which will be of the legacy version), and use that upgrade to turn the contract into proxy contract pattern. From this point on, the contract can upgrade its VM version. The only potential drawback is just that it will costs slightly more gas (another DELEGATECALL) and use one more call frame depth, because we turned previously one indirection into double indirection.

@sorpaas
Copy link
Owner Author

sorpaas commented Jun 21, 2019

Just did another update to EIP-1702 -- I'm making the version of the execution frame always the same as the account code's version. That is, when fetching code from an account in state, we always fetch the version field of that account together, and "associate" the version with the code. This should be easier to implement (we just need to change all definition of code into (code, version) tuple), and it should provide more sensible results for DELEGATECALL/CALLCODE.

@holiman
Copy link

holiman commented Jun 24, 2019

Is it possible to remove the variants that are not to be implemented?

@sorpaas
Copy link
Owner Author

sorpaas commented Jun 24, 2019

@sorpaas
Copy link
Owner Author

sorpaas commented Jun 24, 2019

Previously we also discussed (most regarding state rent) of how we should order additional account RLP fields. Now I'm thinking, maybe we can just use 1702's version fields to order all other additional fields -- read version field first, and then interpret all fields after version as defined by that particular version. This will not only allow us to add new fields, but also allow us to remove fields if necessary!

I added this to 1702 spec. Note that this will not require any change for current 1702 implementations, but I think it may help us implement things like state rent in the future.

@gumb0
Copy link

gumb0 commented Jun 27, 2019

You removed Alternative Design, but it's still mentioned in Rationale.

@gumb0
Copy link

gumb0 commented Jun 27, 2019

I've been implementing this in aleth (ethereum/aleth#5640), and one edge case to be aware of is creating with empty init code (both with creation transaction and CREATE/CREATE2). When init code is empty, creation ends with a new account with empty code and nonce = 1. I've decided to leave it with version 0 in this case, regardless of parent's version and LATEST_VERSION, because other accounts with no code - EOAs - don't have version.
Let me know if I'm not right, and better to clarify it in EIP (and this definitely should go to the test cases)

@gumb0
Copy link

gumb0 commented Jun 27, 2019

Another nit for the spec: maybe it's worth pointing out in Contract Execution section, that contracts with version 0 are executed with Petersburg VM.

@sorpaas
Copy link
Owner Author

sorpaas commented Jun 27, 2019

You removed Alternative Design, but it's still mentioned in Rationale.

Fixed in ethereum#2152. Thanks!

When init code is empty, creation ends with a new account with empty code and nonce = 1.

@gumb0 What do you think if in this case, we keep the version of the account to still be the parent account version? I feel this may be more consistent:

  • We can have different accounts with the same (empty or non-empty) codeHash but with different account versions already. And I feel the situation better falls in this category.
  • VM versioning is expected to handle empty codeHash just like any other code -- it's expected to spin up the required VM of the particular version and attempt to execute the "code". (Of course, in case if code is empty, there're many shortcuts we can take.)
  • If the CREATE init code succeeds, then to better fit the current versioning intention, the resulting contract is expected to have the same version as its parent. I feel it's better to have no exceptions, that is, no matter code is empty or not.

Another nit for the spec: maybe it's worth pointing out in Contract Execution section, that contracts with version 0 are executed with Petersburg VM.

I have small worries that people may still want to apply EVM features to version 0 in Istanbul, until we're all used to account versioning. So maybe we want to finalize this in Istanbul meta EIP but not in EIP-1702.

@gumb0
Copy link

gumb0 commented Jun 27, 2019

I think I don't mind either way, it's either slight confusion of having empty code accounts with different versions, or slight confusion of family of contracts not always producing their version.

Version 0 takes less space to store account, but I guess it shouldn't be significant difference here, as it's a rare case anyway.

It might become important to always produce strictly the same version, if at some point your idea about parsing additional fields based on version field is implemented.
(but to me that idea feels like conflating "version of code executor" and "version of account format", so I'm not completely sure it's good)

@sorpaas
Copy link
Owner Author

sorpaas commented Jun 27, 2019

Version 0 takes less space to store account, but I guess it shouldn't be significant difference here, as it's a rare case anyway.

Yeah agreed. I think it won't make much difference in storage size as it's only a corner case.

It might become important to always produce strictly the same version, if at some point your idea about parsing additional fields based on version field is implemented.

I think this may be a good reason to keep empty-code account (note it's not empty account!) of the parent account's version. Consider if we implement state rent via some additional fields with versions, then by using this scheme we can make sure those new empty-code account are garbage collected. However, if we set empty-code account to version zero, then this won't work.

Conflating "version of code executor" and "version of account format"

I don't think this is actually a bad thing. In the contrary, for some EIPs this is strictly needed. Consider EIP-2027, where we keep a contract size counter as an additional field in the account -- the code executor must support contract size counter (by slightly changing behavior of SSTORE) to make the spec work. It's nearly impossible to completely separate them out.

So if it's okay for you, maybe let's keep the current behavior (empty-code account has the same version of parent account)!

@fulldecent
Copy link

EIP-1702 Account Versioning is a bad idea at this time and it should not be in Istanbul.

a) The only relevant motivation is preparing for emergency last minute hard forks.
b) Other use cases don't exist.

If eWASM launches in 2030, it will be better to deploy this dependency at that time.


This reminds me back in 2013 when we were made our wedding gift registry at Bed Bath and Beyond. The salesperson was trying to sell us a mixer. We told him we don't make cakes. Then he said "well you plan to have kids right? so when your kids go to school you can make cakes for the rest of the class." We said "okay so we get married next year, have a kid and they're in first grade in the year 2021 and then I'll be thinking 'wow I wish a had a vintage 2013 model mixer'".

@MrChico
Copy link

MrChico commented Nov 15, 2019

A minor comment wrt the extension for Contract Creation Transaction scheme is that it would be nice to make the version field optional here as well, and interpret no version as the default 0 version. This would yield a lot more backwards capability. Maybe this is already intended behaviour. If so it needs to be clarified in the specification.

@gumb0
Copy link

gumb0 commented Nov 15, 2019

@MrChico it's there

Check the RLP list length, if it is 4, then set account version to 0, and do not parse any additional fields.

@MrChico
Copy link

MrChico commented Nov 15, 2019

@gumb0 Sorry, my comment was referring to the extension for creating transactions. I have updated it for clarification

@sorpaas
Copy link
Owner Author

sorpaas commented Nov 15, 2019

@MrChico You're right! I edited the 43-VERTXN spec so that version field is optional.

@BelfordZ
Copy link

BelfordZ commented Jun 1, 2020

Hi @sorpaas I read this a long time ago, and once more today. I thought this time I would ask some questions.

  1. Are there any ideas for automatic / manual upgrading of an accounts version?
  2. In the case of the 'emergency hard fork' situation, would the accounts with the offending version remain untouched?
  3. "precompiled contracts don't have version" - Does this mean that accounts with a version which did not implement a particular opcode may now have that opcode implemented?
  4. Contract create TX would always use latest version - I don't know why that would be better than allowing any valid version.
  5. Would the network need to achieve consensus on a list of valid versions? What prevents someone from mining a block with a version that no one else has?

Thanks!

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

No branches or pull requests

7 participants