Conversation
|
I was wondering how much effort is it to change |
|
We should wait a bit until we introduce the next breaking changes. We can keep |
| Json::Value method; | ||
| method["type"] = "function"; | ||
| method["name"] = it.second->declaration().name(); | ||
| method["constant"] = it.second->isConstant(); |
There was a problem hiding this comment.
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)
| Token::Value token = m_scanner->currentToken(); | ||
| if (token == Token::Const) | ||
| // FIXME: constant should be removed | ||
| if (token == Token::Const || token == Token::View) |
There was a problem hiding this comment.
This already leaves the constant keyword as a backwards compatibility change.
|
@chriseth actually the code was like that, supports the Internally though I think it makes sense just moving to view / pure. |
| addSourceFromDocStrings(m_currentContract.contract->annotation()); | ||
|
|
||
| if (_function.isDeclaredConst()) | ||
| if (_function.isPure() || _function.isView()) |
There was a problem hiding this comment.
@pirapira shouldn't this be only isPure?
There was a problem hiding this comment.
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.
71b7e03 to
036b292
Compare
|
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. |
| bool _isDeclaredConst, | ||
| std::vector<ASTPointer<ModifierInvocation>> const& _modifiers, | ||
| ASTPointer<ParameterList> const& _returnParameters, | ||
| bool _isView, |
There was a problem hiding this comment.
If they all contradict each other, perhaps we should create an enum?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
The name of the enum should match the name we use in the ABI below.
| { | ||
| "name": "f", | ||
| "constant": false, | ||
| "view": false, |
There was a problem hiding this comment.
This also looks like having an enum at the API level would make sense.
There was a problem hiding this comment.
Enum of constant, view, pure?
Constant == view, it is just left in the ABI JSON for backwards compatibility.
There was a problem hiding this comment.
What about something like "promise": "view" or "constant": "view"?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
vp-qualifiers (no, I just looked up how C does it)
side-effects, purity, information-flow?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { ... }
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
The only case not handled by this is deliberate memory changes via inline assembly.
I will, the plan for this PR here is only be the non-breaking change. Re: enforcing, please review this: #992 (comment) |
5156e84 to
f0f6b59
Compare
9fdbd99 to
188a0f2
Compare
5d956a5 to
ce5f252
Compare
47ea26f to
e791805
Compare
| 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()), |
There was a problem hiding this comment.
Need to change to isView().
|
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:
|
711d672 to
dba969a
Compare
| // 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(); |
There was a problem hiding this comment.
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)mutabilitywith valuespure,view,write,payable(this is the part to be decided)
5e050a2 to
7de262d
Compare
|
Split out first step as #2722. |
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.
viewandpurecannot useSSTOREviewandpurecannot be payableviewandpurecannot send etherviewcannot call functions not declaredvieworpurepurecannot call functions not declaredpurepurecannot useSLOADpurecannot usemsg.*andblock.*viewandpureare mutually exclusivevieworpurevieworpureconstantas an alias forviewin the parserconstantas an alias forviewin the JSON ABIFurther things to be sorted:
selfdestruct,log(events),this.balance,address.balance,tx.*,newRelated: #992.