Skip to content

Commit

Permalink
refactor: add back forking and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
NotPeopling2day authored and fubuloubu committed Sep 23, 2023
1 parent f283078 commit 1355aa8
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 7 deletions.
16 changes: 10 additions & 6 deletions ape_tenderly/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
from ape import plugins

from .provider import TenderlyGatewayProvider
from .provider import TenderlyForkProvider, TenderlyGatewayProvider

NETWORKS = {
"ethereum": [
"mainnet",
"goerli",
"sepolia",
("mainnet", TenderlyGatewayProvider),
("mainnet-fork", TenderlyForkProvider),
("goerli", TenderlyGatewayProvider),
("sepolia", TenderlyGatewayProvider),
],
"fantom": [
("opera-fork", TenderlyForkProvider),
],
}


@plugins.register(plugins.ProviderPlugin)
def providers():
for ecosystem_name in NETWORKS:
for network_name in NETWORKS[ecosystem_name]:
yield ecosystem_name, network_name, TenderlyGatewayProvider
for network_name, provider in NETWORKS[ecosystem_name]:
yield ecosystem_name, network_name, provider
36 changes: 35 additions & 1 deletion ape_tenderly/provider.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
import os

import requests
from ape.api import UpstreamProvider, Web3Provider
from ape.exceptions import ProviderError
from ape.exceptions import ConfigError, ProviderError
from ape.utils import cached_property
from web3 import HTTPProvider, Web3
from web3.gas_strategies.rpc import rpc_gas_price_strategy
from web3.middleware import geth_poa_middleware

TENDERLY_FORK_ID = "TENDERLY_FORK_ID"
TENDERLY_FORK_SERVICE_URI = "TENDERLY_FORK_SERVICE_URI"


class TenderlyForkProvider(Web3Provider):
@cached_property
def fork_id(self) -> str:
if TENDERLY_FORK_ID in os.environ:
return os.environ[TENDERLY_FORK_ID]

elif TENDERLY_FORK_SERVICE_URI in os.environ:
fork_network_name = self.network.name.replace("-fork", "")
chain_id = self.network.ecosystem.get_network(fork_network_name).chain_id
response = requests.post(
os.environ[TENDERLY_FORK_SERVICE_URI],
json={"network_id": str(chain_id)},
)
return response.json()["simulation_fork"]["id"]

else:
raise ConfigError("No valid tenderly fork ID found.")

@property
def uri(self) -> str:
return f"https://rpc.tenderly.co/fork/{self.fork_id}"

def connect(self):
self._web3 = Web3(HTTPProvider(self.uri))

def disconnect(self):
self._web3 = None


class TenderlyGatewayProvider(Web3Provider, UpstreamProvider):
"""
Expand Down
File renamed without changes.
28 changes: 28 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import ape
import pytest


@pytest.fixture
def networks():
return ape.networks


@pytest.fixture
def accounts():
return ape.accounts


@pytest.fixture
def Contract():
return ape.Contract


@pytest.fixture
def mainnet_fork(networks):
return networks.ethereum.mainnet_fork


@pytest.fixture
def mainnet_fork_provider(mainnet_fork):
with mainnet_fork.use_provider("tenderly") as provider:
yield provider
43 changes: 43 additions & 0 deletions tests/test_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os

import pytest
from ape.exceptions import ConfigError

from ape_tenderly.provider import TENDERLY_FORK_ID


@pytest.fixture(autouse=True)
def connected_eth_mainnet_provider(mainnet_fork_provider):
"""
See README for info on how to set the environment variable.
Else, tests will not run.
"""
if TENDERLY_FORK_ID not in os.environ:
pytest.fail(f"{TENDERLY_FORK_ID} environment variable is required to run tests.")

return mainnet_fork_provider


@pytest.fixture
def unset_fork_id(mainnet_fork_provider):
fork_id = os.environ.pop(TENDERLY_FORK_ID)
was_cached = "fork_id" in mainnet_fork_provider.__dict__
if was_cached:
del mainnet_fork_provider.__dict__["fork_id"]

yield

os.environ[TENDERLY_FORK_ID] = fork_id
if was_cached:
mainnet_fork_provider.__dict__["fork_id"] = fork_id


def test_fork_id_and_uri(connected_eth_mainnet_provider):
provider = connected_eth_mainnet_provider
assert provider.fork_id
assert provider.uri


def test_fork_id_missing(mainnet_fork_provider, unset_fork_id):
with pytest.raises(ConfigError, match="No valid tenderly fork ID found."):
_ = mainnet_fork_provider.fork_id

0 comments on commit 1355aa8

Please sign in to comment.