Skip to content

[WIP] Replace the constant keyword with pure and view for functions#1049

Closed
axic wants to merge 3 commits intodevelopfrom
view-pure
Closed

[WIP] Replace the constant keyword with pure and view for functions#1049
axic wants to merge 3 commits intodevelopfrom
view-pure

Conversation

@axic
Copy link
Copy Markdown
Contributor

@axic axic commented Sep 8, 2016

  • view and pure cannot use SSTORE
  • view and pure cannot be payable
  • view and pure cannot send ether
  • view cannot call functions not declared view or pure
  • pure cannot call functions not declared pure
  • pure cannot use SLOAD
  • pure cannot use msg.* and block.*
  • view and pure are mutually exclusive
  • constructor cannot be view or pure
  • fallback cannot be view or pure
  • include constant as an alias for view in the parser
  • include constant as an alias for view in the JSON ABI
  • update grammar.txt

Further things to be sorted: selfdestruct, log (events), this.balance, address.balance, tx.*, new

Related: #992.

@axic
Copy link
Copy Markdown
Contributor Author

axic commented Sep 8, 2016

I was wondering how much effort is it to change constant to view / pure. This PR can be closed if we think it is too early (as the design is not finalised yet).

@chriseth
Copy link
Copy Markdown
Contributor

chriseth commented Sep 9, 2016

We should wait a bit until we introduce the next breaking changes. We can keep constant as an alias for view for now.

Json::Value method;
method["type"] = "function";
method["name"] = it.second->declaration().name();
method["constant"] = it.second->isConstant();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will leave this in as a deprecated field which we can remove in the breaking release. (So it will have both constant and view set)

Comment thread libsolidity/parsing/Parser.cpp Outdated
Token::Value token = m_scanner->currentToken();
if (token == Token::Const)
// FIXME: constant should be removed
if (token == Token::Const || token == Token::View)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This already leaves the constant keyword as a backwards compatibility change.

@axic
Copy link
Copy Markdown
Contributor Author

axic commented Oct 5, 2016

@chriseth actually the code was like that, supports the constant keyword as an alias for view. I'll add back the JSON ABI field too.

Internally though I think it makes sense just moving to view / pure.

Comment thread libsolidity/formal/Why3Translator.cpp Outdated
addSourceFromDocStrings(m_currentContract.contract->annotation());

if (_function.isDeclaredConst())
if (_function.isPure() || _function.isView())
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@pirapira shouldn't this be only isPure?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No. If it isView(), the function should not change the state, so it's reasonable to assert that the new state is equal to the original state.

@axic axic force-pushed the view-pure branch 3 times, most recently from 71b7e03 to 036b292 Compare October 8, 2016 01:36
@chriseth chriseth changed the title Replace the constant keyword with pure and view for functions [WIP] Breaing: Replace the constant keyword with pure and view for functions [WIP] Oct 10, 2016
@chriseth chriseth changed the title Breaing: Replace the constant keyword with pure and view for functions [WIP] Breaking: Replace the constant keyword with pure and view for functions [WIP] Oct 10, 2016
@chriseth
Copy link
Copy Markdown
Contributor

Please reduce the number of items to be done for this issue - they are a hell of a lot of work. There already is an issue about "enforcing the constant keyword", so please move some of this stuff there, potentially create new issues and interlink them.

Comment thread libsolidity/ast/AST.h Outdated
bool _isDeclaredConst,
std::vector<ASTPointer<ModifierInvocation>> const& _modifiers,
ASTPointer<ParameterList> const& _returnParameters,
bool _isView,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If they all contradict each other, perhaps we should create an enum?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Only view & pure does. (And payable.)

I feel it would hinder future development, because no one would like to get rid of such an enum (pure, view, regular, payable) if it is added.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If view, pure and payable are all mutually exclusive, the danger of having an inconsistent function type at any point is far worse than potentially hindering development.

Furthermore, we should always actively strive against any cargo cult thinking, so that these kinds of arguments are non-issues.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The name of the enum should match the name we use in the ABI below.

{
"name": "f",
"constant": false,
"view": false,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This also looks like having an enum at the API level would make sense.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Enum of constant, view, pure?

Constant == view, it is just left in the ABI JSON for backwards compatibility.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What about something like "promise": "view" or "constant": "view"?

Copy link
Copy Markdown
Contributor Author

@axic axic Nov 18, 2016

Choose a reason for hiding this comment

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

If we want a single field, we should come up with a better name. I think constant is definitely a no go and promise might be ok.

We have to consider the three states we have: regular (might find a better name), view, pure. They differ in their state changing ability.

mutability, mutates, mutate?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

vp-qualifiers (no, I just looked up how C does it)

side-effects, purity, information-flow?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

From yesterday's call:

We have the following types (from most restricted / smallest subset of instructions): pure, view, non-payable, regular/payable.

It can be represented as state-access with levels of none, read-only, non-payable, full.

It may be beneficial to make separation of state and memory access. Think about internal pure functions which work on a memory reference - can they change data?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Memory-avoiding: contained, isolated, confined

I'm starting to think that we may be better with having a syntax similar to modifiers for these: memory(changes), memory(intact), or may be alone memory for those which change the memory after finishing.

Just like C inline assembly has its clobber list.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Did we consider a variant where state-changes are an attribute of the function but memory-changes are attributes of the function arguments? I guess creating new objects in newly allocated memory should be fine for functions that do not alter memory, because I think altering memory should essentially not be about memory as a whole, but only about pre-existing objects in memory.
So we can just apply a constant keyword to function arguments of reference type (it does not make sense for return values) and for complex variables, this constant keyword is pulled all the way through.
If we do it like that, is there a way to get more fine-grained access in the future, i.e. you can pass an array where it is fine for the function to add new elements but it is not allowed to alter existing elements? We could add a 'mutable' keyword that negates the effect of 'constant' starting from that level.

First iteration allows:

function f(uint[][] constant x) { ... }

Second iteration allows:

function f(uint[]constant[] x) { ... }

Copy link
Copy Markdown
Contributor Author

@axic axic Apr 26, 2017

Choose a reason for hiding this comment

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

I'd prefer the keyword immutable instead of constant.

We've have clarified in an offline meeting that view and pure refer to state and make sense in the case of external calls. They do not care about altering memory, because for external calls an individual instance is spinned up and there's no way to access/alter memory after it.

Therefore, we declare that parameters, if pointing to memory, are always mutable and the above is introducing a keyword to mark them immutable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The only case not handled by this is deliberate memory changes via inline assembly.

@chriseth chriseth changed the title Breaking: Replace the constant keyword with pure and view for functions [WIP] Replace the constant keyword with pure and view for functions [WIP] Oct 10, 2016
@axic
Copy link
Copy Markdown
Contributor Author

axic commented Oct 10, 2016

@chriseth:

Please reduce the number of items to be done for this issue - they are a hell of a lot of work.

I will, the plan for this PR here is only be the non-breaking change.

Re: enforcing, please review this: #992 (comment)

@chriseth chriseth added soon and removed in progress labels Oct 28, 2016
@axic axic force-pushed the view-pure branch 2 times, most recently from 5156e84 to f0f6b59 Compare November 15, 2016 02:20
@axic axic force-pushed the view-pure branch 5 times, most recently from 9fdbd99 to 188a0f2 Compare November 21, 2016 11:29
@axic axic changed the title Replace the constant keyword with pure and view for functions [WIP] [WIP] Replace the constant keyword with pure and view for functions Feb 6, 2017
@axic axic force-pushed the view-pure branch 2 times, most recently from 5d956a5 to ce5f252 Compare March 22, 2017 11:13
@axic axic force-pushed the view-pure branch 2 times, most recently from 47ea26f to e791805 Compare May 5, 2017 22:08
@chriseth chriseth added the Focus label May 31, 2017
make_pair("payable", _node.isPayable()),
make_pair("visibility", visibility(_node.visibility())),
// FIXME: remove with next breaking release
make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Need to change to isView().

@axic
Copy link
Copy Markdown
Contributor Author

axic commented Jun 13, 2017

I think once tests are fixed, this could be merged as is (it just introduces the keywords).

We could change it to an enum as agreed, though we never could settle on a naming:

  • Mutability: pure, view, regular/nonpayable, payable.
  • StateAccess: none, read-only, non-payable, full/payable.

@axic axic force-pushed the view-pure branch 2 times, most recently from 711d672 to dba969a Compare June 30, 2017 23:55
// FIXME: constant should be removed at the next breaking release
method["constant"] = it.second->isView();
method["view"] = it.second->isView();
method["pure"] = it.second->isPure();
Copy link
Copy Markdown
Contributor Author

@axic axic Jul 1, 2017

Choose a reason for hiding this comment

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

Once we decide on a naming, the ABI should be:

  • constant (legacy field, to be removed in the future)
  • payable (legacy field, to be removed in the future)
  • mutability with values pure, view, write, payable (this is the part to be decided)

@axic
Copy link
Copy Markdown
Contributor Author

axic commented Aug 9, 2017

Split out first step as #2722.

@axic
Copy link
Copy Markdown
Contributor Author

axic commented Aug 16, 2017

Closing this in favour of the new smaller PRs: #2745 and #2762.

@axic axic closed this Aug 16, 2017
@axic axic deleted the view-pure branch August 16, 2017 21:08
axic pushed a commit that referenced this pull request Nov 20, 2018
This change makes information in ENR compatible with the existing
discovery protocol:

- The default identity scheme is now called "v4" to make the name shorter.
- Node addresses are derived as the hash of the uncompressed public key.
- The "ip4" and "ip6" keys are merged into a single "ip" key which
  can hold a IPv4 or IPv6 address.
- The "discv5" key is now called "udp".
- The new "tcp" key holds the TCP port.
axic pushed a commit to ipsilon/solidity that referenced this pull request Apr 22, 2025
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.

5 participants