abi-gen/Py: fix incorrect method return types and other small issues (#2345)

* .gitignore gen'd Python staking contract wrappers

* abi-gen/test-cli: check Python type hints in lint

* sra_client.py: Update doc for replicating examples

* abi-gen/Py: fix call() return type incl. tx hash

Previously, generated wrappers for contract methods were including type
hints that suggested that a call() (as opposed to a send_transaction())
might return either the underlying return type or a transaction hash.
This doesn't make sense because a call() will never return a TX hash.
Now, the type hint just has the return type of the underlying method.

* abi-gen: fix test_cli:lint checking wrong code

test_cli:lint is meant to be a rudimentary test of the code generated by
abi-gen.  However, previously, this script was incorporated into `yarn
lint`, and in CircleCI `static-tests` runs independently of `build`.
Consequently, the runs of test_cli:lint were checking the OLD code,
which was previously generated and checked in to git, NOT the code
generated with the version of abi-gen represented by the git repo.  Now,
test_cli:lint happens during `yarn test` rather than `yarn lint`,
because `yarn test` IS dependent on `yarn build`.

* contract_wrappers.py: fix misplaced doc

Previously, the routines `order_to_jsdict()` and `jsdict_to_order()`
were moved from contract_wrappers.exchange.types to
contract_wrappers.order_conversions.  However, the module-level
docstring describing those routines was accidentally left behind in
exchange.types.

* abi-gen/Py: stop documenting return types for TXs

Previously the send_transaction() interface included docstring
documentation for the return types of the contract method, but that
doesn't make any sense because send_transaction() returns a transaction
hash rather than any actual return values.

* abi-gen/Py: stop gen'ing send_tx for const methods

* abi-gen/Py: add build_tx to contract methods

* abi-gen/Py: fix incorrect method return types

Fixes #2298 .

* abi-gen/Py: rm validator arg to no-input methods

* abi-gen: mv Py Handlebars helpers to own module

Move all existing Python-related Handlebars helpers to the newly created
python_handlebars_helpers module.

* abi-gen: refactor internal interface

No functionality is changed.  Sole purpose of this commit is to
facilitate an upcoming commit.

* abi-gen: refactor internal interface

No functionality is changed.  Sole purpose of this commit is to
facilitate an upcoming commit.

* abi-gen/Py: name tuples w/internalType, not hash

Use the new `internalType` field on the `DataItem`s in the contract
artifact to give generated tuple classes a better name than just hashing
their component field names.

* Fix CI errors

* abi-gen/Py/wrapper: make internal member private

* Update CHANGELOGs
This commit is contained in:
F. Eugene Aumson
2019-11-15 18:27:45 -05:00
committed by GitHub
parent 9e3cc379ed
commit df97b20913
31 changed files with 679 additions and 847 deletions

View File

@@ -9,6 +9,11 @@
- Moved methods `jsdict_to_order()` and `order_to_jsdict()` from `zero_ex.contract_wrappers.exchange.types` to `zero_ex.contract_wrappers.order_conversions`.
- Changed field name `zero_ex.contract_wrappers.tx_params.TxParams.gasPrice` to `.gas_price`.
- Migrated to new version of 0x-contract-addresses.
- Made the `underlying_method` field on ContractMethod private by prefixing its name with an underscore.
- Corrected return types and values for call() interface to generated method wrappers. (Fixes #2298.)
- Removed `send_transaction()` method from ContractMethod instances for underlying Solidity methods that are const (view/pure).
- Added a `build_transaction()` method to instances of ContractMethod for non-const Solidity methods.
- Removed `validator` argument from ContractMethod instances for underlying Solidity methods that lack inputs.
## 1.1.0 - 2019-08-14

View File

@@ -201,23 +201,23 @@ zero_ex.contract_wrappers.exchange.types
zero_ex.contract_wrappers.exchange: Generated Tuples
====================================================
.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0x6ca34a6f
.. autoclass:: zero_ex.contract_wrappers.exchange.LibOrderOrder
This is the generated class representing `the Order struct <https://0x.org/docs/contracts#structs-Order>`_.
.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0x735c43e3
.. autoclass:: zero_ex.contract_wrappers.exchange.LibFillResultsFillResults
This is the generated class representing `the FillResults struct <https://0x.org/docs/contracts#structs-FillResults>`_.
.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0x4c5ca29b
.. autoclass:: zero_ex.contract_wrappers.exchange.LibFillResultsMatchedFillResults
This is the generated class representing `the MatchedFillResults struct <https://0x.org/docs/contracts#structs-MatchedFillResults>`_.
.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0xb1e4a1ae
.. autoclass:: zero_ex.contract_wrappers.exchange.LibOrderOrderInfo
This is the generated class representing `the OrderInfo struct <https://0x.org/docs/contracts#structs-OrderInfo>`_.
.. autoclass:: zero_ex.contract_wrappers.exchange.Tuple0xdabc15fe
.. autoclass:: zero_ex.contract_wrappers.exchange.LibZeroExTransactionZeroExTransaction
This is the generated class representing `the ZeroExTransaction struct <https://0x.org/docs/contracts#structs-ZeroExTransaction>`_.

View File

@@ -171,7 +171,7 @@ Now we'll have our Taker fill the order.
But before filling an order, one may wish to check that it's actually fillable:
>>> from zero_ex.contract_wrappers.exchange.types import OrderStatus
>>> OrderStatus(exchange.get_order_info.call(order)[0])
>>> OrderStatus(exchange.get_order_info.call(order)["orderStatus"])
<OrderStatus.FILLABLE: 3>
The `takerAssetAmount`:code: parameter specifies the amount of tokens (in this
@@ -181,13 +181,18 @@ completely, but partial fills are possible too.
One may wish to first call the method in a read-only way, to ensure that it
will not revert, and to validate that the return data is as expected:
>>> exchange.fill_order.call(
>>> from pprint import pprint
>>> pprint(exchange.fill_order.call(
... order=order,
... taker_asset_fill_amount=order["takerAssetAmount"],
... signature=maker_signature,
... tx_params=TxParams(from_=taker_address)
... )
(100000000000000000, 100000000000000000, 0, 0, 0)
... ))
{'makerAssetFilledAmount': 100000000000000000,
'makerFeePaid': 0,
'protocolFeePaid': 0,
'takerAssetFilledAmount': 100000000000000000,
'takerFeePaid': 0}
Finally, submit the transaction:
@@ -203,7 +208,6 @@ the exchange wrapper:
>>> exchange.get_fill_event(tx_hash)
(AttributeDict({'args': ...({'makerAddress': ...}), 'event': 'Fill', ...}),)
>>> from pprint import pprint
>>> pprint(exchange.get_fill_event(tx_hash)[0].args.__dict__)
{'feeRecipientAddress': '0x0000000000000000000000000000000000000000',
'makerAddress': '0x...',

View File

@@ -5,20 +5,16 @@ encountered in the Exchange contract's ABI. However, they have weird names,
containing hashes of the tuple's field names, because the name of a Solidity
`struct`:code: isn't conveyed through the ABI. This module provides type
aliases with human-friendly names.
Converting between the JSON wire format and the types accepted by Web3.py (eg
`bytes` vs `str`) can be onerous. This module provides conveniences for
converting Exchange structs between JSON and Python objects.
"""
from enum import auto, Enum
from . import (
Tuple0x735c43e3,
Tuple0x6ca34a6f,
Tuple0x4c5ca29b,
Tuple0xdabc15fe,
Tuple0xb1e4a1ae,
LibFillResultsFillResults,
LibOrderOrder,
LibFillResultsMatchedFillResults,
LibZeroExTransactionZeroExTransaction,
LibOrderOrderInfo,
)
@@ -29,43 +25,43 @@ from . import (
# of each of these classes.
class FillResults(Tuple0x735c43e3):
class FillResults(LibFillResultsFillResults):
"""The `FillResults`:code: Solidity struct.
Also known as
`zero_ex.contract_wrappers.exchange.Tuple0x735c43e3`:py:class:.
`zero_ex.contract_wrappers.exchange.LibFillResultsFillResults`:py:class:.
"""
class Order(Tuple0x6ca34a6f):
class Order(LibOrderOrder):
"""The `Order`:code: Solidity struct.
Also known as
`zero_ex.contract_wrappers.exchange.Tuple0x6ca34a6f`:py:class:.
`zero_ex.contract_wrappers.exchange.LibOrderOrder`:py:class:.
"""
class MatchedFillResults(Tuple0x4c5ca29b):
class MatchedFillResults(LibFillResultsMatchedFillResults):
"""The `MatchedFillResults`:code: Solidity struct.
Also known as
`zero_ex.contract_wrappers.exchange.Tuple0x4c5ca29b`:py:class:.
`zero_ex.contract_wrappers.exchange.LibFillResultsMatchedFillResults`:py:class:.
"""
class ZeroExTransaction(Tuple0xdabc15fe):
class ZeroExTransaction(LibZeroExTransactionZeroExTransaction):
"""The `ZeroExTransaction`:code: Solidity struct.
Also known as
`zero_ex.contract_wrappers.exchange.Tuple0xdabc15fe`:py:class:.
`zero_ex.contract_wrappers.exchange.LibZeroExTransactionZeroExTransaction`:py:class:.
"""
class OrderInfo(Tuple0xb1e4a1ae):
class OrderInfo(LibOrderOrderInfo):
"""The `OrderInfo`:code: Solidity struct.
Also known as
`zero_ex.contract_wrappers.exchange.Tuple0xb1e4a1ae`:py:class:.
`zero_ex.contract_wrappers.exchange.LibOrderOrderInfo`:py:class:.
"""

View File

@@ -1,4 +1,9 @@
"""Utilities to convert between JSON and Python-native objects."""
"""Utilities to convert between JSON and Python-native objects.
Converting between the JSON wire format and the types accepted by Web3.py (eg
`bytes` vs `str`) can be onerous. This module provides conveniences for
converting Exchange structs between JSON and Python objects.
"""
from copy import copy
from typing import cast, Dict, Union

View File

@@ -91,11 +91,11 @@ def test_exchange_wrapper__fill_order(
signature=order_signature,
tx_params=TxParams(from_=taker),
)
assert fill_results[0] == 1
assert fill_results[1] == 1
assert fill_results[2] == 0
assert fill_results[3] == 0
assert fill_results[4] == 0
assert fill_results["makerAssetFilledAmount"] == 1
assert fill_results["takerAssetFilledAmount"] == 1
assert fill_results["makerFeePaid"] == 0
assert fill_results["takerFeePaid"] == 0
assert fill_results["protocolFeePaid"] == 0
tx_hash = exchange_wrapper.fill_order.send_transaction(
order=order,

View File

@@ -32,37 +32,12 @@ configured to connect to any JSON-RPC endpoint, on any network. The examples
below assume that Launch Kit is connected to a Ganache development network
accessible at `http://localhost:8545`:code:.
To replicate this setup, one could run the following commands:
::
docker run -d -p 8545:8545 0xorg/ganache-cli
docker run -d -p 60557:60557 --network host \
-e ETHEREUM_RPC_URL=http://localhost:8545 \
-e ETHEREUM_NETWORK_ID=50 \
-e ETHEREUM_CHAIN_ID=1337 \
-e USE_BOOTSTRAP_LIST=false \
-e VERBOSITY=3 \
-e PRIVATE_KEY_PATH= \
-e BLOCK_POLLING_INTERVAL=5s \
-e P2P_LISTEN_PORT=60557
0xorg/mesh:6.0.0-beta-0xv3
docker run -d --network host \
-e RPC_URL=http://localhost:8545 \
-e CHAIN_ID=1337 \
-e FEE_RECIPIENT=0x0000000000000000000000000000000000000001 \
-e MAKER_FEE_UNIT_AMOUNT=0 \
-e TAKER_FEE_UNIT_AMOUNT=0
-e MESH_ENDPOINT=ws://localhost:60557
-e WHITELIST_ALL_TOKENS=True \
0xorg/launch-kit-ci
(Note: This will only work on Linux, because `--network host`:code: only works
on Linux. For other platforms one would have to clone `the 0x-launch-kit-backend
repository <https://github.com/0xProject/0x-launch-kit-backend>`_ and build and start
the server.)
These examples are automatically verified by spinning up docker images
`0xorg/ganache-cli`, `0xorg/mesh`, and `0xorg/launch-kit-backend`. You can
replicate this environment yourself by using `this docker-compose.yml file
<https://github.com/0xProject/0x-monorepo/blob/development/python-packages/sra_client/test/relayer/docker-compose.yml>`_.
(Note: This will only work on Linux, because it uses `network_mode:
"host"`:code:, which only works on Linux.)
Configure and create an API client instance
-------------------------------------------