Skip to content

Commit

Permalink
Relax ethpm canonical address requirement
Browse files Browse the repository at this point in the history
  • Loading branch information
njgheorghita committed Jul 11, 2019
1 parent 598c852 commit f2f40c7
Show file tree
Hide file tree
Showing 16 changed files with 52 additions and 132 deletions.
9 changes: 4 additions & 5 deletions docs/ethpm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ LinkableContract

.. doctest::

>>> from eth_utils import is_address, to_canonical_address
>>> from eth_utils import is_address
>>> from web3 import Web3
>>> from ethpm import Package, ASSETS_DIR

Expand All @@ -104,7 +104,7 @@ LinkableContract
>>> safe_send_tx_receipt = w3.eth.waitForTransactionReceipt(safe_send_tx_hash)

>>> # Link Escrow factory to deployed SafeSendLib instance
>>> LinkedEscrowFactory = EscrowFactory.link_bytecode({"SafeSendLib": to_canonical_address(safe_send_tx_receipt.contractAddress)})
>>> LinkedEscrowFactory = EscrowFactory.link_bytecode({"SafeSendLib": safe_send_tx_receipt.contractAddress})
>>> assert LinkedEscrowFactory.needs_bytecode_linking is False
>>> escrow_tx_hash = LinkedEscrowFactory.constructor(w3.eth.accounts[0]).transact()
>>> escrow_tx_receipt = w3.eth.waitForTransactionReceipt(escrow_tx_hash)
Expand Down Expand Up @@ -725,7 +725,6 @@ This is the simplest builder function for adding a deployment to a manifest. All

.. doctest::

>>> from eth_utils import to_canonical_address
>>> expected_manifest = {
... 'package_name': 'owned',
... 'manifest_version': '2',
Expand All @@ -734,7 +733,7 @@ This is the simplest builder function for adding a deployment to a manifest. All
... 'blockchain://1234567890123456789012345678901234567890123456789012345678901234/block/1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef': {
... 'Owned': {
... 'contract_type': 'Owned',
... 'address': '0x4f5b11c860b37b68de6d14fb7e7b5f18a9a1bd00',
... 'address': '0x4F5B11C860B37B68De6d14FB7e7b5f18A9a1BD00',
... }
... }
... }
Expand All @@ -745,7 +744,7 @@ This is the simplest builder function for adding a deployment to a manifest. All
... block_uri='blockchain://1234567890123456789012345678901234567890123456789012345678901234/block/1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
... contract_instance='Owned',
... contract_type='Owned',
... address=to_canonical_address('0x4f5b11c860b37b68de6d14fb7e7b5f18a9a1bd00'),
... address='0x4F5B11C860B37B68De6d14FB7e7b5f18A9a1BD00',
... ),
... )
>>> assert expected_manifest == built_manifest
Expand Down
20 changes: 8 additions & 12 deletions ethpm/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
combomethod,
is_canonical_address,
to_bytes,
to_checksum_address,
to_canonical_address,
)
from eth_utils.toolz import (
assoc,
Expand All @@ -24,10 +24,12 @@
ValidationError,
)
from ethpm.validation.misc import (
validate_address,
validate_empty_bytes,
)
from web3 import Web3
from web3._utils.validation import (
validate_address,
)
from web3.contract import (
Contract,
)
Expand All @@ -49,10 +51,7 @@ def __init__(self, address: bytes, **kwargs: Any) -> None:
"Contract cannot be instantiated until its bytecode is linked."
)
validate_address(address)
# todo: remove automatic checksumming of address once web3 dep is updated in pytest-ethereum
super(LinkableContract, self).__init__(
address=to_checksum_address(address), **kwargs
)
super(LinkableContract, self).__init__(address=address, **kwargs)

@classmethod
def factory(
Expand Down Expand Up @@ -125,11 +124,7 @@ def validate_attr_dict(self, attr_dict: Dict[str, str]) -> None:
"`link_bytecode` on a contract factory."
)
for address in attr_dict.values():
if not is_canonical_address(address):
raise BytecodeLinkingError(
f"Address: {address} as specified in the attr_dict is not "
"a valid canoncial address."
)
validate_address(address)


def is_prelinked_bytecode(bytecode: bytes, link_refs: List[Dict[str, Any]]) -> bool:
Expand Down Expand Up @@ -173,8 +168,9 @@ def apply_link_ref(offset: int, length: int, value: bytes, bytecode: bytes) -> b
except ValidationError:
raise BytecodeLinkingError("Link references cannot be applied to bytecode")

address = value if is_canonical_address(value) else to_canonical_address(value)
new_bytes = (
# Ignore linting error b/c conflict b/w black & flake8
bytecode[:offset] + value + bytecode[offset + length:] # noqa: E201, E203
bytecode[:offset] + address + bytecode[offset + length:] # noqa: E201, E203
)
return new_bytes
6 changes: 1 addition & 5 deletions ethpm/deployments.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
List,
)

from eth_utils import (
to_canonical_address,
)

from ethpm.exceptions import (
ValidationError,
)
Expand Down Expand Up @@ -64,7 +60,7 @@ def get_instance(self, contract_name: str) -> None:
# in case the deployment uses a contract alias
contract_type = self.deployment_data[contract_name]["contract_type"]
factory = self.contract_factories[contract_type]
address = to_canonical_address(self.deployment_data[contract_name]["address"])
address = self.deployment_data[contract_name]["address"]
contract_kwargs = {
"abi": factory.abi,
"bytecode": factory.bytecode,
Expand Down
9 changes: 5 additions & 4 deletions ethpm/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
validate_raw_manifest_format,
)
from ethpm.validation.misc import (
validate_address,
validate_w3_instance,
)
from ethpm.validation.package import (
Expand All @@ -73,6 +72,9 @@
validate_single_matching_uri,
)
from web3 import Web3
from web3._utils.validation import (
validate_address,
)
from web3.eth import (
Contract,
)
Expand Down Expand Up @@ -275,9 +277,8 @@ def get_contract_instance(self, name: ContractName, address: Address) -> Contrac
contract_kwargs = generate_contract_factory_kwargs(
self.manifest["contract_types"][name]
)
canonical_address = to_canonical_address(address)
contract_instance = self.w3.eth.contract(
address=canonical_address, **contract_kwargs
address=address, **contract_kwargs
)
return contract_instance

Expand Down Expand Up @@ -347,7 +348,7 @@ def deployments(self) -> Union["Deployments", Dict[None, None]]:
if linked_deployments:
for deployment_data in linked_deployments.values():
on_chain_bytecode = self.w3.eth.getCode(
to_canonical_address(deployment_data["address"])
deployment_data["address"]
)
unresolved_linked_refs = normalize_linked_references(
deployment_data["runtime_bytecode"]["link_dependencies"]
Expand Down
10 changes: 5 additions & 5 deletions ethpm/tools/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
is_hex,
is_string,
to_bytes,
to_checksum_address,
to_dict,
to_hex,
to_list,
)
from eth_utils.toolz import (
Expand Down Expand Up @@ -62,13 +62,13 @@
from ethpm.validation.manifest import (
validate_manifest_against_schema,
)
from ethpm.validation.misc import (
validate_address,
)
from ethpm.validation.package import (
validate_package_name,
)
from web3 import Web3
from web3._utils.validation import (
validate_address,
)


def build(obj: Dict[str, Any], *fns: Callable[..., Any]) -> Dict[str, Any]:
Expand Down Expand Up @@ -705,7 +705,7 @@ def _build_deployments_object(
Returns a dict with properly formatted deployment data.
"""
yield "contract_type", contract_type
yield "address", to_hex(address)
yield "address", to_checksum_address(address)
if deployment_bytecode:
yield "deployment_bytecode", deployment_bytecode
if compiler:
Expand Down
22 changes: 0 additions & 22 deletions ethpm/validation/misc.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,9 @@
from typing import (
Any,
)

from eth_utils import (
is_address,
is_canonical_address,
)

from ethpm.exceptions import (
ValidationError,
)
from web3 import Web3


def validate_address(address: Any) -> None:
"""
Raise a ValidationError if an address is not canonicalized.
"""
if not is_address(address):
raise ValidationError(f"Expected an address, got: {address}")
if not is_canonical_address(address):
raise ValidationError(
"Py-EthPM library only accepts canonicalized addresses. "
f"{address} is not in the accepted format."
)


def validate_w3_instance(w3: Web3) -> None:
if w3 is None or not isinstance(w3, Web3):
raise ValueError("Package does not have valid web3 instance.")
Expand Down
5 changes: 2 additions & 3 deletions tests/core/pm-module/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from eth_utils import (
function_abi_to_4byte_selector,
to_bytes,
to_canonical_address,
)

from ethpm import (
Expand Down Expand Up @@ -160,7 +159,7 @@ def sol_registry(w3):
deployed_registry_package = registry_deployer.deploy("PackageRegistry")
assert isinstance(registry_package, Package)
registry = deployed_registry_package.deployments.get_instance("PackageRegistry")
return SolidityReferenceRegistry(to_canonical_address(registry.address), w3)
return SolidityReferenceRegistry(registry.address, w3)


def vy_registry(w3):
Expand All @@ -171,7 +170,7 @@ def vy_registry(w3):
deployed_registry_package = registry_deployer.deploy("registry")
registry_instance = deployed_registry_package.deployments.get_instance("registry")
assert registry_instance.functions.owner().call() == w3.eth.defaultAccount
return VyperReferenceRegistry(to_canonical_address(registry_instance.address), w3)
return VyperReferenceRegistry(registry_instance.address, w3)


def release_packages(registry):
Expand Down
14 changes: 5 additions & 9 deletions tests/core/pm-module/test_pm_init.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import json
import pytest

from eth_utils import (
to_canonical_address,
)

from ethpm import (
Package,
)
Expand Down Expand Up @@ -38,7 +34,7 @@ def test_get_contract_factory_with_valid_owned_manifest(w3):
owned_factory = owned_package.get_contract_factory('Owned')
tx_hash = owned_factory.constructor().transact()
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
owned_address = to_canonical_address(tx_receipt.contractAddress)
owned_address = tx_receipt.contractAddress
owned_instance = owned_package.get_contract_instance("Owned", owned_address)
assert owned_instance.abi == owned_factory.abi

Expand All @@ -49,7 +45,7 @@ def test_get_contract_factory_with_valid_safe_math_lib_manifest(w3):
safe_math_factory = safe_math_package.get_contract_factory("SafeMathLib")
tx_hash = safe_math_factory.constructor().transact()
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
safe_math_address = to_canonical_address(tx_receipt.contractAddress)
safe_math_address = tx_receipt.contractAddress
safe_math_instance = safe_math_package.get_contract_instance("SafeMathLib", safe_math_address)
assert safe_math_instance.functions.safeAdd(1, 2).call() == 3

Expand All @@ -62,12 +58,12 @@ def test_get_contract_factory_with_valid_escrow_manifest(w3):
safe_send_factory = escrow_package.get_contract_factory('SafeSendLib')
safe_send_tx_hash = safe_send_factory.constructor().transact()
safe_send_tx_receipt = w3.eth.waitForTransactionReceipt(safe_send_tx_hash)
safe_send_address = to_canonical_address(safe_send_tx_receipt.contractAddress)
safe_send_address = safe_send_tx_receipt.contractAddress
linked_escrow_factory = escrow_factory.link_bytecode({"SafeSendLib": safe_send_address})
assert linked_escrow_factory.needs_bytecode_linking is False
escrow_tx_hash = linked_escrow_factory.constructor(w3.eth.accounts[0]).transact()
escrow_tx_receipt = w3.eth.waitForTransactionReceipt(escrow_tx_hash)
escrow_address = to_canonical_address(escrow_tx_receipt.contractAddress)
escrow_address = escrow_tx_receipt.contractAddress
escrow_instance = linked_escrow_factory(address=escrow_address)
assert escrow_instance.functions.sender().call() == w3.eth.accounts[0]

Expand All @@ -80,7 +76,7 @@ def test_deploy_a_standalone_package_integration(w3):
# totalSupply = 100
tx_hash = ERC20.constructor(100).transact()
tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
address = to_canonical_address(tx_receipt["contractAddress"])
address = tx_receipt["contractAddress"]
erc20 = w3.eth.contract(address=address, abi=ERC20.abi)
total_supply = erc20.functions.totalSupply().call()
assert total_supply == 100
Expand Down
12 changes: 5 additions & 7 deletions tests/ethpm/integration/test_escrow_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_deployed_escrow_and_safe_send(escrow_manifest, w3):
"0x4F5B11c860b37b68DE6D14Fb7e7b5f18A9A1bdC0"
).transact()
escrow_tx_receipt = w3.eth.waitForTransactionReceipt(escrow_tx_hash)
escrow_address = to_canonical_address(escrow_tx_receipt.contractAddress)
escrow_address = escrow_tx_receipt.contractAddress

# Cannot deploy with an unlinked factory
with pytest.raises(BytecodeLinkingError):
Expand All @@ -53,9 +53,7 @@ def test_deployed_escrow_and_safe_send(escrow_manifest, w3):
assert EscrowFactory.needs_bytecode_linking is True
assert LinkedEscrowFactory.needs_bytecode_linking is False
assert isinstance(contract_instance, web3.contract.Contract)
assert to_canonical_address(safe_send_address) in LinkedEscrowFactory.bytecode
assert (
to_canonical_address(safe_send_address) in LinkedEscrowFactory.bytecode_runtime
)
assert to_canonical_address(safe_send_address) not in EscrowFactory.bytecode
assert to_canonical_address(safe_send_address) not in EscrowFactory.bytecode_runtime
assert safe_send_address in LinkedEscrowFactory.bytecode
assert safe_send_address in LinkedEscrowFactory.bytecode_runtime
assert safe_send_address not in EscrowFactory.bytecode
assert safe_send_address not in EscrowFactory.bytecode_runtime
8 changes: 2 additions & 6 deletions tests/ethpm/test_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,14 @@
"escrow",
"Escrow",
{
"SafeSendLib": to_canonical_address(
"0x4F5B11c860b37b68DE6D14Fb7e7b5f18A9A1bdC0"
)
"SafeSendLib": "0x4F5B11c860b37b68DE6D14Fb7e7b5f18A9A1bdC0"
},
),
(
"wallet",
"Wallet",
{
"SafeMathLib": to_canonical_address(
"0xa66A05D6AB5c1c955F4D2c3FCC166AE6300b452B"
)
"SafeMathLib": "0xa66A05D6AB5c1c955F4D2c3FCC166AE6300b452B"
},
),
),
Expand Down
3 changes: 1 addition & 2 deletions tests/ethpm/test_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from eth_utils import (
is_same_address,
to_canonical_address,
)

from ethpm.exceptions import (
Expand All @@ -26,7 +25,7 @@ def deployed_safe_math(safe_math_package, w3):
SafeMath = safe_math_package.get_contract_factory("SafeMathLib")
tx_hash = SafeMath.constructor().transact()
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
return safe_math_package, to_canonical_address(tx_receipt.contractAddress)
return safe_math_package, tx_receipt.contractAddress


def test_package_object_instantiates_with_a_web3_object(all_manifests, w3):
Expand Down
Loading

0 comments on commit f2f40c7

Please sign in to comment.