protocol/python-packages/order_utils/test/test_signature_utils.py
F. Eugene Aumson e61f23d001
Migrate Python libraries to v3 (#2284)
* .gitignore migrations/0x_ganache_snapshot

* .gitignore new-ish Python contract wrappers

These should have been added back when we started generating these
wrappers.

* rm superfluous contract artifact in Python package

All of the contract artifacts were removed from the Python package
recently, because now they're copied from the monorepo/packages area as
an automated build step.  Somehow this one artifact slipped through the
cracks.

* Eliminate circular dependency

This was preventing the Exchange wrapper from ever importing its
validator!

* Improve output of monorepo-level parallel script

- Capture stderr (and have it included in stdout) so that it doesn't
leak onto the console for commands that didn't actually fail.

- Include all error output in the Exception object (eliminate print
statement).

* Silence new versions of linters

Newer versions care about this stuff.  Old versions didn't, and we don't
either.

* Support Rich Reverts via Web3.py middleware

* Fix bug in generated wrappers' bytes handling

`bytes.fromhex(bytes.decode('utf-8')` is just plain wrong.  It would
work for some cases, but is not working when trying to fill orders with
the latest Exchange contract.

* Migrate to Exchange v3

* Fix typo in DevUtils documentation

* Include new contracts in docs

* Re-enable Python checks in CI

* Accept strings for bytes

* Fix CircleCI build artifacts for gen'd python

I swear the previous way was working before, but it wasn't working now,
so this fixes it.

* Accept a provider OR a Web3 object

In various places.  This allows the caller to install middleware (which
in web3.py is installed on a Web3 object, not on a provider) before
executing any RPC calls, which is important for the case where one wants
to produce signatures locally before submitting to a remote node.

* wrapper base: don't assume there are accounts

* Eliminate some inline linter directives

* make CHANGELOGs be REVERSE chronological

* Update CHANGELOG entries and bump version numbers

* @0x/contract-addresses: Put addr's in JSON, not TS

This allows easier consumption by other languages.  (Specifically, it
eliminates the overhead of keeping the Python addresses package in sync
with the TypeScript one.)

* sra_client.py: incl. docker in `./setup.py clean`

* sra_client.py: Migrate to protocol v3

Removed script that existed only to exclude runs of sra_client builds
(parallel_without_sra_client).  Now `parallel` is used by CI,
re-including sra_client in CI checks.

* abi-gen/templates/Py: clarify if/else logic

In response to
https://github.com/0xProject/0x-monorepo/pull/2284#discussion_r342200906

* sra_client.py: Update CHANGELOG and bump version

* contract_addresses/setup.py: rm unnecessary rm

* json_schemas.py: corrections to dev dependencies

* In tests against deployment, also run doctests

* contract_wrappers example: rm xtra Order attribute

Thanks to @steveklebanoff for catching this.
https://github.com/0xProject/0x-monorepo/pull/2284#pullrequestreview-312065368
2019-11-05 23:04:29 -05:00

170 lines
6.1 KiB
Python

"""Tests of zero_ex.order_utils.signature_utils."""
import pytest
from web3 import Web3
from zero_ex.contract_wrappers.exchange.exceptions import (
SignatureError,
SignatureErrorCodes,
)
from zero_ex.order_utils import is_valid_signature, sign_hash_to_bytes
def test_is_valid_signature__provider_wrong_type():
"""Test that giving a non-HTTPProvider raises a TypeError."""
with pytest.raises(TypeError):
is_valid_signature(
123,
"0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
+ "0",
"0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
+ "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
+ "225403",
"0x5409ed021d9299bf6814279a6a1411a7e866a631",
)
def test_is_valid_signature__data_not_string():
"""Test that giving non-string `data` raises a TypeError."""
with pytest.raises(TypeError):
is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
123,
"0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
+ "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
+ "225403",
"0x5409ed021d9299bf6814279a6a1411a7e866a631",
)
def test_is_valid_signature__data_not_hex_string():
"""Test that giving non-hex-string `data` raises a ValueError."""
with pytest.raises(ValueError):
is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
"jjj",
"0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
+ "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
+ "225403",
"0x5409ed021d9299bf6814279a6a1411a7e866a631",
)
def test_is_valid_signature__signature_not_string():
"""Test that passng a non-string signature raises a TypeError."""
with pytest.raises(TypeError):
is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
"0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
+ "0",
123,
"0x5409ed021d9299bf6814279a6a1411a7e866a631",
)
def test_is_valid_signature__signature_not_hex_string():
"""Test that passing a non-hex-string signature raises a ValueError."""
with pytest.raises(ValueError):
is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
"0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
+ "0",
"jjj",
"0x5409ed021d9299bf6814279a6a1411a7e866a631",
)
def test_is_valid_signature__signer_address_not_string():
"""Test that giving a non-address `signer_address` raises a ValueError."""
with pytest.raises(TypeError):
is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
"0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
+ "0",
"0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
+ "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
+ "225403",
123,
)
def test_is_valid_signature__signer_address_not_hex_string():
"""Test that giving a non-hex-str `signer_address` raises a ValueError."""
with pytest.raises(ValueError):
is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
"0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
+ "0",
"0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
+ "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
+ "225403",
"jjj",
)
def test_is_valid_signature__signer_address_not_valid_address():
"""Test that giving a non-address for `signer_address` raises an error."""
with pytest.raises(ValueError):
is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
"0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
+ "0",
"0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
+ "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
+ "225403",
"0xff",
)
def test_is_valid_signature__unsupported_sig_types():
"""Test that passing in a sig w/invalid type raises error.
To induce this error, the last byte of the signature is tweaked from 03 to
ff."""
try:
is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
"0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222"
+ "b0",
"0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
+ "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
+ "225401",
"0x5409ed021d9299bf6814279a6a1411a7e866a631",
)
except SignatureError as signature_error:
assert (
signature_error.errorCode
== SignatureErrorCodes.INVALID_LENGTH.value
)
else:
pytest.fail("Expected exception")
def test_sign_hash_to_bytes_and_validate__golden_path():
"""Test the happy path through sign_hash_to_bytes()."""
provider = Web3.HTTPProvider("http://127.0.0.1:8545")
signing_address = Web3( # pylint: disable=no-member
provider
).geth.personal.listAccounts()[0]
order_hash_hex = (
"0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004"
)
signature = sign_hash_to_bytes(provider, signing_address, order_hash_hex)
assert (
signature
== b"1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03" # noqa: E501 (line too long)
)
is_valid = is_valid_signature(
Web3.HTTPProvider("http://127.0.0.1:8545"),
order_hash_hex,
signature.decode("utf-8"),
signing_address,
)
assert is_valid is True