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

Generate transient storage layout #15247

Merged
merged 1 commit into from
Aug 2, 2024
Merged

Conversation

matheusaaguiar
Copy link
Collaborator

No description provided.

@matheusaaguiar matheusaaguiar self-assigned this Jul 8, 2024
@matheusaaguiar matheusaaguiar marked this pull request as ready for review July 9, 2024 18:59
libsolidity/interface/StorageLayout.cpp Show resolved Hide resolved
VariableDeclaration::Location location = [&]() {
switch (_location)
{
case DataLocation::Storage: return VariableDeclaration::Location::Unspecified; // By default state variables have unspecified (storage) data location
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this should be refactored in a separate PR so variables at storage are explicitly assigned VariableDeclaration::Location::Storage (note this is a different enum from DataLocation which is in Types.h).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we even need two enums for this? It makes it significantly more annoying in the first place. Adding an Unspecified option to the DataLocation enum would be enough; plus it's not a class member enum so it can be aliased as well (unlike VariableDeclaration::Location). But yeah, a problem for another time.

Copy link
Member

@cameel cameel Jul 26, 2024

Choose a reason for hiding this comment

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

Why do we even need two enums for this?

DataLocation specifies where the data is stored while VariableDeclaration::Location indicates which modifier is on the variable.

I think this should be refactored in a separate PR so variables at storage are explicitly assigned VariableDeclaration::Location::Storage

Unspecified does not necessarily mean Storage. That's the case only for state variables. And even then it may also represent a constant or an immutable.

I think changing the way it works would just make things confusing in a different way. Then we'd be asking why it doesn't reflect what's on the variable :) The current usage does have some logic behind it. This is just another case of things being too vaguely named, omitting important context. Maybe something like DeclaredLocation or LocationModifier would be clearer.

Adding an Unspecified option to the DataLocation enum would be enough;

It would be misleading because this Unspecified would have a different meaning than the one in VariableDeclaration::Location and it still would not be a 1:1 translation, IMO nullopt is a better choice.

Changelog.md Outdated Show resolved Hide resolved
Changelog.md Outdated Show resolved Hide resolved
libsolidity/interface/StorageLayout.cpp Show resolved Hide resolved
libsolidity/ast/Types.cpp Outdated Show resolved Hide resolved
libsolidity/codegen/ir/IRGenerator.cpp Outdated Show resolved Hide resolved
libsolidity/interface/StorageLayout.cpp Outdated Show resolved Hide resolved
libsolidity/ast/Types.cpp Outdated Show resolved Hide resolved
@@ -1103,8 +1115,9 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon
m_context = std::move(newContext);

m_context.setMostDerivedContract(_contract);
for (auto const& var: ContractType(_contract).stateVariables())
m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var));
for (auto const& location: {DataLocation::Storage, DataLocation::Transient})
Copy link
Collaborator

Choose a reason for hiding this comment

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

Might make sense to make the required data location std::optional and set to std::nullopt by default - this would alleviate then need to change both this section of code as well as the one in ContractCompiler.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, I thought about that at first but expected it to be more complicated than what I have actually come up with.

VariableDeclaration::Location location = [&]() {
switch (_location)
{
case DataLocation::Storage: return VariableDeclaration::Location::Unspecified; // By default state variables have unspecified (storage) data location
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we even need two enums for this? It makes it significantly more annoying in the first place. Adding an Unspecified option to the DataLocation enum would be enough; plus it's not a class member enum so it can be aliased as well (unlike VariableDeclaration::Location). But yeah, a problem for another time.

nikola-matic
nikola-matic previously approved these changes Jul 26, 2024
Copy link
Collaborator

@nikola-matic nikola-matic left a comment

Choose a reason for hiding this comment

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

@cameel please take over.

Changelog.md Outdated Show resolved Hide resolved
Changelog.md Outdated Show resolved Hide resolved
Copy link
Member

@cameel cameel left a comment

Choose a reason for hiding this comment

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

Here are a few initial remarks after going through tests.

So far only minor stuff, other than the fact that we haven't even one test covering CLI output. And that docs have not been updated.

Comment on lines 3 to 15
contract A {
uint transient x;
uint y;
int transient z;
int w;
address transient addr;
address d;
bool transient b;
bool c;
}
Copy link
Member

@cameel cameel Jul 26, 2024

Choose a reason for hiding this comment

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

I'd also add some constants and immutables here to make sure they're not included in either layout.

Also different visibilities (public, private, etc.).

Could also be separate tests, but IMO it would be fine to keep it in one test since CLI tests are pretty verbose.

Copy link
Member

@cameel cameel left a comment

Choose a reason for hiding this comment

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

I went through it all now and did not find anything broken. Just a few more testing/styling/wording remarks.

So overall this is mostly fine, just needs docs, CLI coverage, some small tweaks and then we can merge.

libsolidity/interface/StorageLayout.cpp Outdated Show resolved Hide resolved
libsolidity/ast/Types.cpp Outdated Show resolved Hide resolved
libsolidity/analysis/TypeChecker.cpp Show resolved Hide resolved
Changelog.md Outdated Show resolved Hide resolved
Copy link
Collaborator

@nikola-matic nikola-matic left a comment

Choose a reason for hiding this comment

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

You haven't added a cmdline test for --transient-storage-layout yet, right?

Changelog.md Outdated Show resolved Hide resolved
@matheusaaguiar
Copy link
Collaborator Author

You haven't added a cmdline test for --transient-storage-layout yet, right?

No I haven't. I wrote a test case in solc/CommandLineInterface.cpp but the output contains the path to a temporary file which changes everytime and I am not sure how to handle it. See 6b6407c.

@nikola-matic
Copy link
Collaborator

You haven't added a cmdline test for --transient-storage-layout yet, right?

No I haven't. I wrote a test case in solc/CommandLineInterface.cpp but the output contains the path to a temporary file which changes everytime and I am not sure how to handle it. See 6b6407c.

I meant something like this - https://github.com/ethereum/solidity/tree/develop/test/cmdlineTests/ir_subobject_order

@matheusaaguiar
Copy link
Collaborator Author

I meant something like this - https://github.com/ethereum/solidity/tree/develop/test/cmdlineTests/ir_subobject_order

Duh, yeah, I forgot we can do that 😁
Added.

@matheusaaguiar
Copy link
Collaborator Author

We have this section in the docs describing the storage layout and it mentions storage very frequently. I was thinking of a good way to include the information about transient storage. I think that a note explaining that regarding the layout of state variables, and only that, the same rules apply for both storage and transient storage.
Is that a good approach?

Copy link
Member

@cameel cameel left a comment

Choose a reason for hiding this comment

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

A couple of tests have syntax errors and we could use a tiny bit more detail in the docs.

I didn't find anything more serious and these are trivial to fix so you can consider it soft-approved.

@@ -6,6 +6,9 @@ Layout of State Variables in Storage

.. _storage-inplace-encoding:

.. note::
The rules described in this section apply for both storage and transient storage data locations.
Copy link
Member

Choose a reason for hiding this comment

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

I'd still add a few things:

  • Maybe change title to "Layout of State Variables in Storage and Transient Storage"?
  • Say that the layouts are completely independent, i.e. storage variables have zero effect on locations of transient storage variables and vice-versa. They can be safely interleaved.
  • I'd mention that only value types are supported for transient storage.
  • There's a note saying that we consider storage layout a part of the external interface. Is that still true for transient storage? If so, we should say that explicitly.
  • Add an index entry for transient storage, next to storage above.

Copy link
Member

Choose a reason for hiding this comment

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

Also, there's a note way below, saying:

The JSON output format of a contract's storage layout is still considered experimental and is subject to change in non-breaking releases of Solidity.

I don't think it's true any more. When we once broke the layout accidentally in 0.8.x cycle, we considered it very breaking and released a new version a few days later to correct it.

Given that, I wonder if we should now say that about transient storage or is it automatically considered stable by the virtue of being tied to storage layout?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have applied all suggestions, but not sure about the notes regarding external interface.
What do you think @ekpyron?

Copy link
Member

Choose a reason for hiding this comment

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

TBH this is already wrong on develop so it's fine to merge the PR regardless and then fix it separately in a smaller doc-only PR.

test/cmdlineTests/transient_storage_layout/args Outdated Show resolved Hide resolved
@cameel
Copy link
Member

cameel commented Aug 1, 2024

I think that a note explaining that regarding the layout of state variables, and only that, the same rules apply for both storage and transient storage.
Is that a good approach?

I generally agree in that we don't have to create a separate section and just repeat everything verbatim, but I think we could use a tiny bit more mentions than just a single note :) See #15247 (comment)

@nikola-matic
Copy link
Collaborator

Gonna need to squash the commits - still got some fixups in there.

@nikola-matic nikola-matic merged commit 7094e30 into develop Aug 2, 2024
72 checks passed
@nikola-matic nikola-matic deleted the transientStorageLayout branch August 2, 2024 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

3 participants