-
Notifications
You must be signed in to change notification settings - Fork 9
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
Network / Contracts models + CRUD endpoints + Celery Orchestration #44
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of questions:
- Would it be possible to terminate only the workers that have changed in the request?
- I would at least test the client <-> DB interaction in this PR.
- Have you thought about how could we perform integration tests with celery? It does not need to be in this PR but it should be somehow included as it is the critical functionality of the node.
src/__init__.py
Outdated
@@ -36,7 +40,9 @@ def create_app(args: dict = {}) -> Sanic: # noqa: C901 | |||
if app.config["ENABLE_BACKGROUND_WORKER"]: | |||
from src.process.collector import start_collecting | |||
|
|||
asyncio.get_event_loop().run_until_complete(start_collecting(chains)) | |||
@app.listener("after_server_start") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we move this below to have all the hooks on the same place?
src/api/chains.py
Outdated
except ActiveChainFailed as e: | ||
raise NotFound(e) | ||
|
||
await restart_collectors(processor, chains, request.app.db) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I tried curl -X PUT -H "Content-Type: application/json" -d '{"active":true}' localhost:7424/api/chains/eth.mainnet
without the celery worker running this part would fail but the chain status would be updated. Also any other problems would result in the same behaviour. We should either wrap the DB update into transaction or return appropriate message if the collector restart failed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My proposal would be to check if the celery worker is enabled app.config["ENABLE_DATABASE"] == True
. If the celery worker is enabled then we would restart the appropriate celery chain collector. If not then we would do nothing. This will allow the user to configure the desired chain / contract statuses whilst the celery worker is disabled.
@@ -15,8 +15,7 @@ | |||
"src.process.collector.*": {"queue": "collect"}, | |||
"src.process.executor.*": {"queue": "execute"}, | |||
}, | |||
task_serializer="pickle", | |||
accept_content=["json", "pickle"], | |||
accept_content=["json"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
src/api/contracts.py
Outdated
""" | ||
data = request.json | ||
await Contract.create_contract( | ||
request.app.db, data["id"], data["active"], data["chain"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Data should be validated:
- is the given address of a correct format depending on the chain?
src/models/contract.py
Outdated
|
||
__tablename__ = "contracts" | ||
|
||
id = sa.Column(sa.String, primary_key=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Contract
model requires an address
field. With this setup now we cannot have 2 contracts with the same address on 2 different chains (e.g. ETH, BSC). A contract can therefore be uniquely identifiable by a (address
, chain
) tuple.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the address field. I have not had time to change the interfaces to use a (address
, chain
) as a primary key for the contracts. They are currently using the id
field which is an auto-incrementing integer. I can change this tomorrow.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great, thank you. I made a couple of tests locally, it seems to work alright. I had hoped you will include the integration tests: client -> API endpoints -> DB as this is what we care from the FE side but I guess this is fine.
RUN mkdir /home/worker/paralink-node | ||
RUN mkdir /home/worker/paralink-node/data | ||
RUN mkdir -p /home/worker/paralink-node | ||
RUN mkdir -p /home/worker/paralink-node/data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope this does not exposes the system for any vulnerabilities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will resolve this shortly. I was thinking we can provide a build flag to indicate if the root user should be used. We can then toggle root on for github builds and turn it off for operation. What do you think?
@@ -5,4 +5,6 @@ | |||
from src.network.chains import Chains | |||
|
|||
chain_config = Path(config.DATA_FOLDER).joinpath("chain_config.json") | |||
chains = Chains.read_from_json(str(chain_config.absolute())) | |||
chains = Chains.from_list( | |||
json.load(open(Path(config.DATA_FOLDER).joinpath("chain_config.json"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why this cannot use the above chain_config
variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason... just me being blind 😄
@pytest.fixture() | ||
async def tables(engine): | ||
async with engine.begin() as conn: | ||
await conn.run_sync(Base.metadata.create_all) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to migrate or use schema + migrate to spot any issues regarding the migrations. I guess this will do for now. The tables are persisted though, since you do not call drop_all
anywhere. Not a major issue, if we are using a new DB every time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Performing the migration sounds like a sensible thing to do. I will see about changing this.
This PR introduces database tables for both chains and contracts and associated CRUD endpoints to interact with these tables. This will allow the user to activate / deactivate chains and contracts, and also allows them to add / delete contracts.
When a chain / contract is activated / deactivated / create / deleted, all celery
collector
tasks are terminated and newcollector
tasks are executed to reflect the updated chain statuses.closes #21
supports paralink-network/paralink-ui#10