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

fix: bug where was not smart enough to detect type 2 transactions #21

Merged
merged 3 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ repos:
- id: isort

- repo: https://github.com/psf/black
rev: 23.12.0
rev: 23.12.1
hooks:
- id: black
name: black

- repo: https://github.com/pycqa/flake8
rev: 6.1.0
rev: 7.0.0
hooks:
- id: flake8

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.7.1
rev: v1.8.0
hooks:
- id: mypy
additional_dependencies: [types-setuptools, pydantic]
Expand Down
76 changes: 2 additions & 74 deletions ape_bsc/ecosystem.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
from typing import Dict, Optional, Type, cast
from typing import Optional, Type, cast

from ape.api import TransactionAPI
from ape.api.config import PluginConfig
from ape.api.networks import LOCAL_NETWORK_NAME
from ape.types import TransactionSignature
from ape.utils import DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT
from ape_ethereum.ecosystem import Ethereum, ForkedNetworkConfig, NetworkConfig
from ape_ethereum.transactions import DynamicFeeTransaction, StaticFeeTransaction, TransactionType
from ape_ethereum.transactions import TransactionType

NETWORKS = {
# chain_id, network_id
Expand Down Expand Up @@ -51,73 +49,3 @@ class BSC(Ethereum):
@property
def config(self) -> BSCConfig: # type: ignore[override]
return cast(BSCConfig, self.config_manager.get_config("bsc"))

def create_transaction(self, **kwargs) -> TransactionAPI:
"""
Returns a transaction using the given constructor kwargs.
Overridden because does not support

**kwargs: Kwargs for the transaction class.

Returns:
:class:`~ape.api.transactions.TransactionAPI`
"""

transaction_types: Dict[int, Type[TransactionAPI]] = {
TransactionType.STATIC.value: StaticFeeTransaction,
TransactionType.DYNAMIC.value: DynamicFeeTransaction,
}

if "type" in kwargs:
if kwargs["type"] is None:
# The Default is pre-EIP-1559.
version = self.default_transaction_type.value
elif not isinstance(kwargs["type"], int):
version = self.conversion_manager.convert(kwargs["type"], int)
else:
version = kwargs["type"]

elif "gas_price" in kwargs:
version = TransactionType.STATIC.value
else:
version = self.default_transaction_type.value

kwargs["type"] = version
txn_class = transaction_types[version]

if "required_confirmations" not in kwargs or kwargs["required_confirmations"] is None:
# Attempt to use default required-confirmations from `ape-config.yaml`.
required_confirmations = 0
active_provider = self.network_manager.active_provider
if active_provider:
required_confirmations = active_provider.network.required_confirmations

kwargs["required_confirmations"] = required_confirmations

if isinstance(kwargs.get("chainId"), str):
kwargs["chainId"] = int(kwargs["chainId"], 16)

elif "chainId" not in kwargs and self.network_manager.active_provider is not None:
kwargs["chainId"] = self.provider.chain_id

if "input" in kwargs:
kwargs["data"] = kwargs.pop("input")

if all(field in kwargs for field in ("v", "r", "s")):
kwargs["signature"] = TransactionSignature(
v=kwargs["v"],
r=bytes(kwargs["r"]),
s=bytes(kwargs["s"]),
)

if "max_priority_fee_per_gas" in kwargs:
kwargs["max_priority_fee"] = kwargs.pop("max_priority_fee_per_gas")
if "max_fee_per_gas" in kwargs:
kwargs["max_fee"] = kwargs.pop("max_fee_per_gas")

kwargs["gas"] = kwargs.pop("gas_limit", kwargs.get("gas"))

if "value" in kwargs and not isinstance(kwargs["value"], int):
kwargs["value"] = self.conversion_manager.convert(kwargs["value"], int)

return txn_class(**kwargs)
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"hypothesis>=6.2.0,<7.0", # Strategy-based fuzzer
],
"lint": [
"black>=23.12.0,<24", # Auto-formatter and linter
"mypy>=1.7.1,<2", # Static type analyzer
"black>=23.12.1,<24", # Auto-formatter and linter
"mypy>=1.8.0,<2", # Static type analyzer
"types-setuptools", # Needed for mypy type shed
"flake8>=6.1.0,<7", # Style linter
"flake8>=7.0.0,<8", # Style linter
"flake8-breakpoint>=1.1.0,<2", # Detect breakpoints left in code
"flake8-print>=5.0.0,<6", # Detect print statements left in code
"isort>=5.10.1,<6", # Import sorting linter
Expand Down Expand Up @@ -60,7 +60,7 @@
url="https://github.com/ApeWorX/ape-bsc",
include_package_data=True,
install_requires=[
"eth-ape>=0.7.0,<0.8",
"eth-ape>=0.7.5,<0.8",
],
python_requires=">=3.8,<4",
extras_require=extras_require,
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def bsc(networks):
return networks.bsc


@pytest.fixture
@pytest.fixture(autouse=True)
def eth_tester_provider():
if not ape.networks.active_provider or ape.networks.provider.name != "test":
with ape.networks.bsc.local.use_provider("test") as provider:
Expand Down
38 changes: 33 additions & 5 deletions tests/test_ecosystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,39 @@ def test_gas_limit(bsc):
assert bsc.config.local.gas_limit == "max"


@pytest.mark.parametrize("tx_type", (None, 0, "0x0"))
def test_create_transaction(bsc, tx_type, eth_tester_provider):
tx = bsc.create_transaction(type=tx_type)
assert tx.type == TransactionType.STATIC.value
assert tx.gas_limit == eth_tester_provider.max_gas
@pytest.mark.parametrize(
"tx_kwargs",
[
{}, # Default is type 0 in BSC.
{"type": 0},
{"gas_price": 0},
{"gasPrice": 0},
],
)
def test_create_transaction_type_0(bsc, tx_kwargs):
txn = bsc.create_transaction(**tx_kwargs)
assert txn.type == TransactionType.STATIC.value


@pytest.mark.parametrize(
"tx_kwargs",
[
{"type": 2},
{"max_fee": 0},
{"max_fee_per_gas": 0},
{"maxFee": 0},
{"max_priority_fee_per_gas": 0},
{"max_priority_fee": 0},
{"maxPriorityFeePerGas": 0},
],
)
def test_create_transaction_type_2(bsc, tx_kwargs):
"""
Show is smart-enough to deduce type 2 transactions.
"""

txn = bsc.create_transaction(**tx_kwargs)
assert txn.type == TransactionType.DYNAMIC.value


@pytest.mark.parametrize(
Expand Down