Skip to content

Commit

Permalink
chore: fix some documentation inconsistencies (#3624)
Browse files Browse the repository at this point in the history
* raw_args kwarg to create_from_blueprint
* fix create_from_blueprint example
* clarify "all but one 64th" behavior when forwarding gas left=
* remove dead comment
* update internal documentation for generate_ir_for_external_function()
* update memory layout in create_from_blueprint comments
* fix warning for BitwiseNot
* fix error message about msg.data
* docs: extract32 can output any bytesM type
* remove dead variable in comment
  • Loading branch information
charles-cooper authored Sep 26, 2023
1 parent 7b9d159 commit e5c323a
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 17 deletions.
13 changes: 9 additions & 4 deletions docs/built-in-functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,14 @@ Vyper has three built-ins for contract creation; all three contract creation bui
The implementation of ``create_copy_of`` assumes that the code at ``target`` is smaller than 16MB. While this is much larger than the EIP-170 constraint of 24KB, it is a conservative size limit intended to future-proof deployer contracts in case the EIP-170 constraint is lifted. If the code at ``target`` is larger than 16MB, the behavior of ``create_copy_of`` is undefined.


.. py:function:: create_from_blueprint(target: address, *args, value: uint256 = 0, code_offset=0, [, salt: bytes32]) -> address
.. py:function:: create_from_blueprint(target: address, *args, value: uint256 = 0, raw_args: bool = False, code_offset: int = 0, [, salt: bytes32]) -> address
Copy the code of ``target`` into memory and execute it as initcode. In other words, this operation interprets the code at ``target`` not as regular runtime code, but directly as initcode. The ``*args`` are interpreted as constructor arguments, and are ABI-encoded and included when executing the initcode.

* ``target``: Address of the blueprint to invoke
* ``*args``: Constructor arguments to forward to the initcode.
* ``value``: The wei value to send to the new contract address (Optional, default 0)
* ``raw_args``: If ``True``, ``*args`` must be a single ``Bytes[...]`` argument, which will be interpreted as a raw bytes buffer to forward to the create operation (which is useful for instance, if pre- ABI-encoded data is passed in from elsewhere). (Optional, default ``False``)
* ``code_offset``: The offset to start the ``EXTCODECOPY`` from (Optional, default 0)
* ``salt``: A ``bytes32`` value utilized by the deterministic ``CREATE2`` opcode (Optional, if not supplied, ``CREATE`` is used)

Expand All @@ -201,7 +202,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
@external
def foo(blueprint: address) -> address:
arg1: uint256 = 18
arg2: String = "some string"
arg2: String[32] = "some string"
return create_from_blueprint(blueprint, arg1, arg2, code_offset=1)
.. note::
Expand All @@ -226,7 +227,7 @@ Vyper has three built-ins for contract creation; all three contract creation bui
* ``to``: Destination address to call to
* ``data``: Data to send to the destination address
* ``max_outsize``: Maximum length of the bytes array returned from the call. If the returned call data exceeds this length, only this number of bytes is returned. (Optional, default ``0``)
* ``gas``: The amount of gas to attach to the call. If not set, all remaining gas is forwarded.
* ``gas``: The amount of gas to attach to the call. (Optional, defaults to ``msg.gas``).
* ``value``: The wei value to send to the address (Optional, default ``0``)
* ``is_delegate_call``: If ``True``, the call will be sent as ``DELEGATECALL`` (Optional, default ``False``)
* ``is_static_call``: If ``True``, the call will be sent as ``STATICCALL`` (Optional, default ``False``)
Expand Down Expand Up @@ -264,6 +265,10 @@ Vyper has three built-ins for contract creation; all three contract creation bui
assert success
return response
.. note::

Regarding "forwarding all gas", note that, while Vyper will provide ``msg.gas`` to the call, in practice, there are some subtleties around forwarding all remaining gas on the EVM which are out of scope of this documentation and could be subject to change. For instance, see the language in EIP-150 around "all but one 64th".

.. py:function:: raw_log(topics: bytes32[4], data: Union[Bytes, bytes32]) -> None
Provides low level access to the ``LOG`` opcodes, emitting a log without having to specify an ABI type.
Expand Down Expand Up @@ -500,7 +505,7 @@ Data Manipulation

* ``b``: ``Bytes`` list to extract from
* ``start``: Start point to extract from
* ``output_type``: Type of output (``bytes32``, ``integer``, or ``address``). Defaults to ``bytes32``.
* ``output_type``: Type of output (``bytesM``, ``integer``, or ``address``). Defaults to ``bytes32``.

Returns a value of the type specified by ``output_type``.

Expand Down
6 changes: 2 additions & 4 deletions vyper/builtins/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,7 @@ class BitwiseNot(BuiltinFunction):

def evaluate(self, node):
if not self.__class__._warned:
vyper_warn("`bitwise_not()` is deprecated! Please use the ^ operator instead.")
vyper_warn("`bitwise_not()` is deprecated! Please use the ~ operator instead.")
self.__class__._warned = True

validate_call_args(node, 1)
Expand Down Expand Up @@ -1917,9 +1917,8 @@ def _build_create_IR(self, expr, args, context, value, salt, code_offset, raw_ar

# copy the target code into memory.
# layout starting from mem_ofst:
# 00...00 (22 0's) | preamble | bytecode
# <target initcode> | <abi-encoded args OR arg buffer if raw_arg=True>
ir.append(["extcodecopy", target, mem_ofst, code_offset, codesize])

ir.append(copy_bytes(add_ofst(mem_ofst, codesize), argbuf, encoded_args_len, bufsz))

# theoretically, dst = "msize", but just be safe.
Expand Down Expand Up @@ -2586,7 +2585,6 @@ def evaluate(self, node):
if isinstance(input_type, IntegerT):
ret = vy_ast.Int.from_node(node, value=val)

# TODO: to change to known_type once #3213 is merged
ret._metadata["type"] = input_type
return ret

Expand Down
11 changes: 4 additions & 7 deletions vyper/codegen/function_definitions/external_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,20 +135,17 @@ def handler_for(calldata_kwargs, default_kwargs):
return ret


# TODO it would be nice if this returned a data structure which were
# amenable to generating a jump table instead of the linear search for
# method_id we have now.
def generate_ir_for_external_function(code, func_t, context):
# TODO type hints:
# def generate_ir_for_external_function(
# code: vy_ast.FunctionDef,
# func_t: ContractFunctionT,
# context: Context,
# check_nonpayable: bool,
# ) -> IRnode:
"""Return the IR for an external function. Includes code to inspect the method_id,
enter the function (nonpayable and reentrancy checks), handle kwargs and exit
the function (clean up reentrancy storage variables)
"""
Return the IR for an external function. Returns IR for the body
of the function, handle kwargs and exit the function. Also returns
metadata required for `module.py` to construct the selector table.
"""
nonreentrant_pre, nonreentrant_post = get_nonreentrant_lock(func_t)

Expand Down
2 changes: 1 addition & 1 deletion vyper/semantics/analysis/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def _validate_msg_data_attribute(node: vy_ast.Attribute) -> None:
allowed_builtins = ("slice", "len", "raw_call")
if not isinstance(parent, vy_ast.Call) or parent.get("func.id") not in allowed_builtins:
raise StructureException(
"msg.data is only allowed inside of the slice or len functions", node
"msg.data is only allowed inside of the slice, len or raw_call functions", node
)
if parent.get("func.id") == "slice":
ok_args = len(parent.args) == 3 and isinstance(parent.args[2], vy_ast.Int)
Expand Down
1 change: 0 additions & 1 deletion vyper/semantics/analysis/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ def __init__(
_ns.update({k: namespace[k] for k in namespace._scopes[-1]}) # type: ignore
module_node._metadata["namespace"] = _ns

# check for collisions between 4byte function selectors
self_members = namespace["self"].typ.members

# get list of internal function calls made by each function
Expand Down

0 comments on commit e5c323a

Please sign in to comment.