Skip to content

feat!: support per network defaults for txn acceptance timeout #911

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

Merged
merged 4 commits into from
Jul 26, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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: 4 additions & 2 deletions docs/userguides/transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,13 @@ Otherwise, you will get an `AttributeError`.
## Transaction Acceptance Timeout

**NOTE** For longer running scripts, you may need to increase the transaction acceptance timeout.
The default value is 2 minutes.
The default value is 2 minutes for live networks and 20 seconds for local networks.
In your `ape-config.yaml` file, add the following:

```yaml
transaction_acceptance_timeout: 600 # 5 minutes
ethereum:
mainnet:
transaction_acceptance_timeout: 600 # 5 minutes
```

## Traces
Expand Down
42 changes: 23 additions & 19 deletions src/ape/api/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@

from ape.exceptions import NetworkError, NetworkNotFoundError, SignatureError
from ape.types import AddressType, ContractLog, RawAddress
from ape.utils import BaseInterfaceModel, abstractmethod, cached_property, raises_not_implemented
from ape.utils import (
DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT,
BaseInterfaceModel,
abstractmethod,
cached_property,
raises_not_implemented,
)

from .config import PluginConfig

Expand Down Expand Up @@ -494,7 +500,7 @@ class NetworkAPI(BaseInterfaceModel):
def __repr__(self) -> str:
return f"<{self.name} chain_id={self.chain_id}>"

@cached_property
@property
def config(self) -> PluginConfig:
"""
The configuration of the network. See :class:`~ape.managers.config.ConfigManager`
Expand All @@ -503,9 +509,9 @@ def config(self) -> PluginConfig:

return self.config_manager.get_config(self.ecosystem.name)

@cached_property
def _network_config(self) -> PluginConfig:
return self.config.dict().get(self.name, {}) # type: ignore
@property
def _network_config(self) -> Dict:
return self.config.dict().get(self.name, {})

@property
def chain_id(self) -> int:
Expand All @@ -514,9 +520,6 @@ def chain_id(self) -> int:

**NOTE**: Unless overridden, returns same as
:py:attr:`ape.api.providers.ProviderAPI.chain_id`.

Returns:
int
"""

provider = self.ecosystem.network_manager.active_provider
Expand All @@ -536,9 +539,6 @@ def network_id(self) -> int:

**NOTE**: Unless overridden, returns same as
:py:attr:`~ape.api.networks.NetworkAPI.chain_id`.

Returns:
int
"""
return self.chain_id

Expand All @@ -549,11 +549,8 @@ def required_confirmations(self) -> int:
before considering a transaction "confirmed". Confirmations
refer to the number of blocks that have been added since the
transaction's block.

Returns:
int
"""
return self._network_config.get("required_confirmations", 0) # type: ignore
return self._network_config.get("required_confirmations", 0)

@property
def block_time(self) -> int:
Expand All @@ -566,12 +563,19 @@ def block_time(self) -> int:
ethereum:
mainnet:
block_time: 15

Returns:
int
"""
return self._network_config.get("block_time", 0)

return self._network_config.get("block_time", 0) # type: ignore
@property
def transaction_acceptance_timeout(self) -> int:
"""
The amount of time to wait for a transaction to be accepted on the network.
Does not include waiting for block-confirmations. Defaults to two minutes.
Local networks use smaller timeouts.
"""
return self._network_config.get(
"transaction_acceptance_timeout", DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT
)

@cached_property
def explorer(self) -> Optional["ExplorerAPI"]:
Expand Down
2 changes: 1 addition & 1 deletion src/ape/api/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ def get_transaction(
raise TransactionError(message="Required confirmations cannot be negative.")

timeout = (
timeout if timeout is not None else self.config_manager.transaction_acceptance_timeout
timeout if timeout is not None else self.provider.network.transaction_acceptance_timeout
)

try:
Expand Down
13 changes: 0 additions & 13 deletions src/ape/managers/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from ethpm_types import PackageMeta

CONFIG_FILE_NAME = "ape-config.yaml"
DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT = 120


class DeploymentConfig(PluginConfig):
Expand Down Expand Up @@ -105,12 +104,6 @@ class ConfigManager(BaseInterfaceModel):
default_ecosystem: str = "ethereum"
"""The default ecosystem to use. Defaults to ``"ethereum"``."""

transaction_acceptance_timeout: int = DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT
"""
The amount of time to wait for a transaction to be accepted on the network.
Does not include waiting for block-confirmations.
"""

_cached_configs: Dict[str, Dict[str, Any]] = {}

@root_validator(pre=True)
Expand Down Expand Up @@ -139,9 +132,6 @@ def _plugin_configs(self) -> Dict[str, PluginConfig]:
self.dependencies = cache.get("dependencies", [])
self.deployments = cache.get("deployments", {})
self.contracts_folder = cache.get("contracts_folder", self.PROJECT_FOLDER / "contracts")
self.transaction_acceptance_timeout = cache.get(
"transaction_acceptance_timeout", DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT
)
return cache

# First, load top-level configs. Then, load all the plugin configs.
Expand All @@ -159,9 +149,6 @@ def _plugin_configs(self) -> Dict[str, PluginConfig]:
self.default_ecosystem = configs["default_ecosystem"] = user_config.pop(
"default_ecosystem", "ethereum"
)
self.transaction_acceptance_timeout = user_config.pop(
"transaction_acceptance_timeout", DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT
)

try:
self.network_manager.set_default_ecosystem(self.default_ecosystem)
Expand Down
4 changes: 4 additions & 0 deletions src/ape/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
)
from ape.utils.github import GithubClient, github_client
from ape.utils.misc import (
DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT,
DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT,
EMPTY_BYTES32,
USER_AGENT,
ZERO_ADDRESS,
Expand Down Expand Up @@ -50,8 +52,10 @@
"BaseInterfaceModel",
"cached_property",
"CallTraceParser",
"DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT",
"DEFAULT_NUMBER_OF_TEST_ACCOUNTS",
"DEFAULT_TEST_MNEMONIC",
"DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT",
"EMPTY_BYTES32",
"expand_environment_variables",
"extract_nested_value",
Expand Down
2 changes: 2 additions & 0 deletions src/ape/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

EMPTY_BYTES32 = HexBytes("0x0000000000000000000000000000000000000000000000000000000000000000")
ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT = 120
DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT = 20

_python_version = (
f"{sys.version_info.major}.{sys.version_info.minor}"
Expand Down
33 changes: 27 additions & 6 deletions src/ape_ethereum/ecosystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
from ape.exceptions import APINotImplementedError, DecodingError, TransactionError
from ape.types import AddressType, ContractLog, RawAddress, TransactionSignature
from ape.utils import (
DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT,
DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT,
LogInputABICollection,
Struct,
StructParser,
Expand Down Expand Up @@ -73,20 +75,39 @@ class NetworkConfig(PluginConfig):
"""

block_time: int = 0
transaction_acceptance_timeout: int = DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT


class EthereumConfig(PluginConfig):
mainnet: NetworkConfig = NetworkConfig(required_confirmations=7, block_time=13) # type: ignore
mainnet_fork: NetworkConfig = NetworkConfig(default_provider=None) # type: ignore
mainnet_fork: NetworkConfig = NetworkConfig(
default_provider=None,
transaction_acceptance_timeout=DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT,
) # type: ignore
ropsten: NetworkConfig = NetworkConfig(required_confirmations=12, block_time=15) # type: ignore
ropsten_fork: NetworkConfig = NetworkConfig(default_provider=None) # type: ignore
ropsten_fork: NetworkConfig = NetworkConfig(
default_provider=None,
transaction_acceptance_timeout=DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT,
) # type: ignore
kovan: NetworkConfig = NetworkConfig(required_confirmations=2, block_time=4) # type: ignore
kovan_fork: NetworkConfig = NetworkConfig(default_provider=None) # type: ignore
kovan_fork: NetworkConfig = NetworkConfig(
default_provider=None,
transaction_acceptance_timeout=DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT,
) # type: ignore
rinkeby: NetworkConfig = NetworkConfig(required_confirmations=2, block_time=15) # type: ignore
rinkeby_fork: NetworkConfig = NetworkConfig(default_provider=None) # type: ignore
rinkeby_fork: NetworkConfig = NetworkConfig(
default_provider=None,
transaction_acceptance_timeout=DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT,
) # type: ignore
goerli: NetworkConfig = NetworkConfig(required_confirmations=2, block_time=15) # type: ignore
goerli_fork: NetworkConfig = NetworkConfig(default_provider=None) # type: ignore
local: NetworkConfig = NetworkConfig(default_provider="test") # type: ignore
goerli_fork: NetworkConfig = NetworkConfig(
default_provider=None,
transaction_acceptance_timeout=DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT,
) # type: ignore
local: NetworkConfig = NetworkConfig(
default_provider="test",
transaction_acceptance_timeout=DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT,
) # type: ignore
default_network: str = LOCAL_NETWORK_NAME


Expand Down
Empty file removed tests/functional/api/__init__.py
Empty file.
10 changes: 1 addition & 9 deletions tests/functional/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

from ape.exceptions import NetworkError
from ape.managers.config import DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT, DeploymentConfigCollection
from ape.managers.config import DeploymentConfigCollection
from tests.functional.conftest import PROJECT_WITH_LONG_CONTRACTS_FOLDER


Expand Down Expand Up @@ -56,14 +56,6 @@ def test_default_provider_not_found(temp_config, networks):
_ = networks.ecosystems


def test_transaction_acceptance_timeout(temp_config, config, networks):
assert config.transaction_acceptance_timeout == DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT
new_value = DEFAULT_TRANSACTION_ACCEPTANCE_TIMEOUT + 10
timeout_config = {"transaction_acceptance_timeout": new_value}
with temp_config(timeout_config):
assert config.transaction_acceptance_timeout == new_value


def test_dependencies(dependency_config, config):
assert len(config.dependencies) == 1
assert config.dependencies[0].name == "testdependency"
Expand Down
12 changes: 12 additions & 0 deletions tests/functional/test_ethereum.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from ape.exceptions import OutOfGasError
from ape.types import AddressType
from ape.utils import DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT
from ape_ethereum.ecosystem import Block
from ape_ethereum.transactions import (
Receipt,
Expand Down Expand Up @@ -109,3 +110,14 @@ def test_block_handles_snake_case_parent_hash(eth_tester_provider, sender, recei

redefined_block = Block.parse_obj(latest_block_dict)
assert redefined_block.parent_hash == latest_block.parent_hash


def test_transaction_acceptance_timeout(temp_config, config, networks):
assert (
networks.provider.network.transaction_acceptance_timeout
== DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT
)
new_value = DEFAULT_LOCAL_TRANSACTION_ACCEPTANCE_TIMEOUT + 1
timeout_config = {"ethereum": {"local": {"transaction_acceptance_timeout": new_value}}}
with temp_config(timeout_config):
assert networks.provider.network.transaction_acceptance_timeout == new_value
File renamed without changes.