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

Increase Anvil default HTTP read timeout to 30s #248

Merged
merged 2 commits into from
Dec 4, 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
10 changes: 10 additions & 0 deletions eth_defi/provider/multi_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def create_multi_provider_web3(
request_kwargs: Optional[Any] = None,
session: Optional[Any] = None,
switchover_noisiness=logging.WARNING,
default_http_timeout=(3.0, 30.0),
) -> MultiProviderWeb3:
"""Create a Web3 instance with multi-provider support.

Expand Down Expand Up @@ -155,8 +156,14 @@ def create_multi_provider_web3(

See :py:class:`web3.HTTPProvider` for details.


Example: ``request_kwargs={"timeout": 10.0}``

:param default_http_timeout:
Use this timeout value for HTTP requests library if `request_kwargs` not given.

Tuple (connect timeout, read timeout)

:param session:
Use specific HTTP 1.1 session with :py:mod:`requests`.

Expand Down Expand Up @@ -211,6 +218,9 @@ def create_multi_provider_web3(
session.mount("http://", adapter)
session.mount("https://", adapter)

if request_kwargs is None:
request_kwargs = {"timeout": default_http_timeout}

call_providers = [HTTPProvider(url, request_kwargs=request_kwargs, session=session) for url in call_endpoints]

# Do uJSON patching
Expand Down
51 changes: 41 additions & 10 deletions tests/velvet/test_velvet_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from web3 import Web3

from eth_defi.hotwallet import HotWallet
from eth_defi.provider.anvil import AnvilLaunch, fork_network_anvil
from eth_defi.provider.anvil import AnvilLaunch, fork_network_anvil, make_anvil_custom_rpc_request
from eth_defi.provider.broken_provider import get_almost_latest_block_number
from eth_defi.provider.multi_provider import create_multi_provider_web3
from eth_defi.token import TokenDetails, fetch_erc20_details
Expand Down Expand Up @@ -49,10 +49,12 @@ def anvil_base_fork(request, vault_owner, usdc_holder, deposit_user) -> AnvilLau

:return: JSON-RPC URL for Web3
"""

assert JSON_RPC_BASE is not None, "JSON_RPC_BASE not set"
launch = fork_network_anvil(
JSON_RPC_BASE,
unlocked_addresses=[vault_owner, usdc_holder, deposit_user],
fork_block_number=23261311,
)
try:
yield launch
Expand All @@ -63,9 +65,30 @@ def anvil_base_fork(request, vault_owner, usdc_holder, deposit_user) -> AnvilLau

@pytest.fixture()
def web3(anvil_base_fork) -> Web3:
web3 = create_multi_provider_web3(anvil_base_fork.json_rpc_url)
assert web3.eth.chain_id == 8453
return web3
"""Create Web3 instance.

- Use mainnet fork with Anvil for local testing

- If symbolic transaction debugging is needed, you can override
Anvil manually with a Tenderly virtual testnet
"""
# Debug using Tenderly debugger
tenderly_fork_rpc = os.environ.get("JSON_RPC_TENDERLY", None)

if tenderly_fork_rpc:
web3 = create_multi_provider_web3(tenderly_fork_rpc)
snapshot = make_anvil_custom_rpc_request(web3, "evm_snapshot")
try:
yield web3
finally:
# Revert Tenderly testnet back to its original state
# https://docs.tenderly.co/forks/guides/testing/reset-transactions-after-completing-the-test
make_anvil_custom_rpc_request(web3, "evm_revert", [snapshot])
else:
# Anvil
web3 = create_multi_provider_web3(anvil_base_fork.json_rpc_url)
assert web3.eth.chain_id == 8453
yield web3


@pytest.fixture()
Expand Down Expand Up @@ -115,7 +138,7 @@ def vault(web3, base_test_vault_spec: VaultSpec) -> VelvetVault:

@pytest.fixture()
def deposit_user() -> HexAddress:
"""A user that has preapproved 5 USDC deposit for the vault above, no approve(0 needed."""
"""A user that has preapproved 5 USDC deposit for the vault above, no approve() needed."""
return "0x7612A94AafF7a552C373e3124654C1539a4486A8"


Expand Down Expand Up @@ -144,7 +167,7 @@ def test_fetch_vault_portfolio(vault: VelvetVault):
assert portfolio.spot_erc20["0x6921B130D297cc43754afba22e5EAc0FBf8Db75b"] > 0


@pytest.mark.skipif(CI, reason="Enso is such unstable crap that there is no hope we could run any tests with in CI")
#@pytest.mark.skipif(CI, reason="Enso is such unstable crap that there is no hope we could run any tests with in CI")
def test_vault_swap_partially(
vault: VelvetVault,
vault_owner: HexAddress,
Expand Down Expand Up @@ -193,7 +216,7 @@ def test_vault_swap_partially(
assert portfolio.spot_erc20["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"] < existing_usdc_balance


@pytest.mark.skipif(CI, reason="Enso is such unstable crap that there is no hope we could run any tests with in CI")
#@pytest.mark.skipif(CI, reason="Enso is such unstable crap that there is no hope we could run any tests with in CI")
def test_vault_swap_very_little(
vault: VelvetVault,
vault_owner: HexAddress,
Expand Down Expand Up @@ -225,7 +248,7 @@ def test_vault_swap_very_little(
assert_transaction_success_with_explanation(web3, tx_hash)


@pytest.mark.skipif(CI, reason="Enso is such unstable crap that there is no hope we could run any tests with in CI")
#@pytest.mark.skipif(CI, reason="Enso is such unstable crap that there is no hope we could run any tests with in CI")
def test_vault_swap_sell_to_usdc(
vault: VelvetVault,
vault_owner: HexAddress,
Expand Down Expand Up @@ -265,7 +288,7 @@ def test_vault_swap_sell_to_usdc(
assert portfolio.spot_erc20["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"] > existing_usdc_balance


@pytest.mark.skipif(CI, reason="Enso is such unstable crap that there is no hope we could run any tests with in CI")
#@pytest.mark.skipif(CI, reason="Enso is such unstable crap that there is no hope we could run any tests with in CI")
def test_velvet_api_deposit(
vault: VelvetVault,
vault_owner: HexAddress,
Expand Down Expand Up @@ -317,7 +340,15 @@ def test_velvet_api_deposit(
)
assert tx_data["to"] == deposit_manager
tx_hash = web3.eth.send_transaction(tx_data)
assert_transaction_success_with_explanation(web3, tx_hash)
try:
assert_transaction_success_with_explanation(web3, tx_hash)
except Exception as e:
# Double check allowance - Anvil bug
allowance = usdc.contract.functions.allowance(
Web3.to_checksum_address(deposit_user),
Web3.to_checksum_address(deposit_manager),
).call()
raise RuntimeError(f"transferFrom() failed, allowance after broadcast {allowance / 10**6} USDC: {e}") from e

# USDC balance has increased after the deposit
portfolio = vault.fetch_portfolio(universe, web3.eth.block_number)
Expand Down
Loading