Skip to content

Commit

Permalink
feat: add filename to deployments db (#345)
Browse files Browse the repository at this point in the history
add filename to deployments db and the appropriate migration
  • Loading branch information
PatrickAlphaC authored Nov 22, 2024
1 parent 08d4c53 commit a1cddb3
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 3 deletions.
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ git commit -m 'your commit message'
git push <your_forked_github>
```

4. Run the linter

```bash
make lint
```

## Running Tests

Once you have your environment setup, you can run the tests to make sure everything is working as expected. You'll need to have your virtual environment activated to run the tests.
Expand Down
15 changes: 14 additions & 1 deletion boa/deployments.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def get_session_id():
class Deployment:
contract_address: Address # receipt_dict["createAddress"]
contract_name: str
filename: str
rpc: str
deployer: Address # ostensibly equal to tx_dict["from"]
tx_hash: str
Expand Down Expand Up @@ -90,6 +91,7 @@ def from_sql_tuple(cls, values):
session_id text,
contract_address text,
contract_name text,
filename text,
rpc text,
deployer text,
tx_hash text,
Expand All @@ -110,9 +112,12 @@ def __init__(self, path=":memory:"):

# once 3.12 is min version, use autocommit=True
self.db = sqlite3.connect(path)

self.db.execute(_CREATE_CMD)

# Migration for legacy DB without filename column
# We can/should remove this after some time (all 4 users migrate)
self._apply_filename_migration()

def __del__(self):
self.db.close()

Expand All @@ -127,6 +132,14 @@ def insert_deployment(self, deployment: Deployment):
self.db.execute(insert_cmd, tuple(values.values()))
self.db.commit()

def _apply_filename_migration(self) -> None:
cursor = self.db.execute("PRAGMA table_info(deployments);")
columns = [col[1] for col in cursor.fetchall()]
is_in_db = "filename" in columns
if is_in_db:
return
self.db.execute("ALTER TABLE deployments ADD COLUMN filename text;")

def _get_deployments_from_sql(self, sql_query: str, parameters=(), /):
cur = self.db.execute(sql_query, parameters)
return (Deployment.from_sql_tuple(item) for item in cur)
Expand Down
2 changes: 2 additions & 0 deletions boa/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ def deploy(

if (deployments_db := get_deployments_db()) is not None:
contract_name = getattr(contract, "contract_name", None)
filename = getattr(contract, "filename", None)
try:
source_bundle = get_verification_bundle(contract)
except Exception as e:
Expand All @@ -419,6 +420,7 @@ def deploy(
deployment_data = Deployment(
create_address,
contract_name,
filename,
self._rpc.name,
sender,
receipt["transactionHash"],
Expand Down
35 changes: 33 additions & 2 deletions tests/integration/network/anvil/test_network_env.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import sqlite3
import tempfile
from pathlib import Path

import pytest
from hypothesis import given, settings

import boa
import boa.test.strategies as vy
from boa.deployments import DeploymentsDB, set_deployments_db
from boa.deployments import _CREATE_CMD, DeploymentsDB, set_deployments_db
from boa.network import NetworkEnv
from boa.rpc import to_bytes
from boa.util.abi import Address
Expand Down Expand Up @@ -77,9 +81,10 @@ def test_deployment_db_overriden_contract_name():
with set_deployments_db(DeploymentsDB(":memory:")) as db:
arg = 5
contract_name = "test_deployment"
filename = "my_filename"

# contract is written to deployments db
contract = boa.loads(code, arg, name=contract_name)
contract = boa.loads(code, arg, name=contract_name, filename=filename)

# test get_deployments()
deployment = next(db.get_deployments())
Expand All @@ -89,6 +94,7 @@ def test_deployment_db_overriden_contract_name():
# sanity check all the fields
assert deployment.contract_address == contract.address
assert deployment.contract_name == contract.contract_name
assert deployment.filename == contract.filename
assert deployment.contract_name == contract_name
assert deployment.deployer == boa.env.eoa
assert deployment.rpc == boa.env._rpc.name
Expand Down Expand Up @@ -117,6 +123,7 @@ def test_deployment_db_no_overriden_name():
# sanity check all the fields
assert deployment.contract_address == contract.address
assert deployment.contract_name == contract.contract_name
assert deployment.filename == "<unknown>"
assert deployment.contract_name != non_contract_name
assert deployment.deployer == boa.env.eoa
assert deployment.rpc == boa.env._rpc.name
Expand All @@ -127,3 +134,27 @@ def test_deployment_db_no_overriden_name():
assert to_bytes(deployment.tx_dict["data"]) == initcode
assert deployment.tx_dict["chainId"] == hex(boa.env.get_chain_id())
assert Address(deployment.receipt_dict["contractAddress"]) == contract.address


@pytest.fixture
def temp_legacy_db_path() -> Path:
temp_dir = Path(tempfile.mkdtemp())
db_path = temp_dir / "test.db"
conn = sqlite3.connect(db_path)
conn.execute(_CREATE_CMD)
DROP_COLUMN_SQL = "ALTER TABLE deployments DROP COLUMN filename;"
conn.execute(DROP_COLUMN_SQL)
return db_path


def test_deployments_db_migration(temp_legacy_db_path):
sql_db = sqlite3.connect(temp_legacy_db_path)
cursor = sql_db.execute("PRAGMA table_info(deployments);")
columns = [col[1] for col in cursor.fetchall()]
assert "filename" not in columns

# This next line is what does the migration (added the filename column)
db = DeploymentsDB(temp_legacy_db_path)
cursor = db.db.execute("PRAGMA table_info(deployments);")
columns = [col[1] for col in cursor.fetchall()]
assert "filename" in columns

0 comments on commit a1cddb3

Please sign in to comment.