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

VIP: msg.data #1181

Closed
nrryuya opened this issue Jan 8, 2019 · 8 comments · Fixed by #2343
Closed

VIP: msg.data #1181

nrryuya opened this issue Jan 8, 2019 · 8 comments · Fixed by #2343

Comments

@nrryuya
Copy link
Contributor

nrryuya commented Jan 8, 2019

Simple Summary

Add support of msg.data, which returns the complete calldata. This enables a proxy for an upgradable pattern.

Abstract

Add a new global variable msg.data similar to the one of Solidity.

Motivation

This enables a proxy for an upgradable pattern with which users don't need to take care of the proxy contract. See the example code below.

Specification

msg.data returns a bytes which represents a complete calldata using CALLDATA opcode.

This is an example code of a proxy contract. (ref OpenZeppelin Proxy.sol)

proxy contract

implementation: public(address)
owner: public(address)

@public
def __default__():
    assert msg.sender == self.owner
    raw_call(self.implementation, msg.data, outsize=0, gas=0, delegate_call=True)
    
@public
def upgradeTo(_newAddr: address):
    assert msg.sender == self.owner
    self.implementation = _newAddr

delegatee contract

dummyVal1: address
dummyVal2: address
appData1: public(uint256)
appData2: public(bytes32)


@public
def someFunc(_inp: uint256):
    self.appData1 = _inp

(NOTE: dummyVals are there to make up for the slots of the variables used only in the proxy. Instead, the slots of these variables are explicitly set with inline assembly in Solidity).

Backwards Compatibility

It's a new feature and backward compatible.

Dependencies

None

Copyright

Copyright and related rights waived via CC0

@jacqueswww
Copy link
Contributor

jacqueswww commented Jan 8, 2019

👍 exposing msg.data is something we need (other type of verifiers can use this too) and is implemented easily :)

@jacqueswww
Copy link
Contributor

jacqueswww commented Jan 10, 2019

I looked at the implementation of this and it gets a bit tricky with the fact that we do not allow any length bytes which means we would have to assert/throw if CALLDATASIZE is larger than the provided/set data type. Which means in vyper msg.data will probably have to the following rules:

  • Special case of raw_call() if used as follows:
raw_call(self.implementation, msg.data, outsize=0, gas=msg.gas, delegate_call=True)  # no assertions occur
  • In any other scenario the bytes will only be copied if msg.data.size <= maxlen e.g. in an assign:
a: bytes[1024] = msg.data  # will throw if  CALLDATASIZE > 1024 

cc @fubuloubu

@fubuloubu
Copy link
Member

What about if I use it directly? Would the accessor be the bound that would check for assert? What if I access multiple parts of it?

@vbuterin
Copy link
Contributor

Special case of raw_call() if used as follows:

The problem with allowing this is that you lose the property of being able to calculate a precise bound on gas consumption.

One alternative proposal would be to allow msg.data ONLY in the form slice(msg.data, x, y) (ie. msg.data as an independent thing would not be legal, this would be an additional rule in the definition of slice)

@fubuloubu
Copy link
Member

The problem with allowing this is that you lose the property of being able to calculate a precise bound on gas consumption.

I think we lose this with raw_call in general. If we make a call to a Solidity contract, I think all bets are off IIRC

@charles-cooper
Copy link
Member

I think an issue with using slice is it makes it easier for the programmer to make mistakes, i.e. failing silently. Perhaps a middle ground is having the syntax be msg.data[len], that way the length is always specified, and the runtime throws if there is a bounds check error.

@djrtwo
Copy link

djrtwo commented Aug 12, 2019

Utilizing msg.data is a path we are considering to help prevent potential validators from losing their deposits due to malformed calldata. Is this still something that is being considered for implementation in the near future?

EDIT: see ethereum/consensus-specs#1357

@fubuloubu
Copy link
Member

It's on the path for the next few months, but we're accepting contributions if anyone wants to get involved! It shouldn't be too difficult.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants