-
Notifications
You must be signed in to change notification settings - Fork 12
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
Facilitator #1
Comments
Nice! 🦖 My comments:
I don't agree. I think it is much easier to implement and maintain, if one facilitator process tracks only a single gateway pair. If you want to track multiple pairs, run multiple instances. Should make configuration, account tracking, etc., etc. much easier. At the same time, I don't see it as extra burden to run multiple processes for multiple chains. In a way, it is even more robust.
Agreed. These could even run in separate, independent sub-processes.
How do different facilitators coordinate? I think this is a huge topic. Maybe out of the scope of the initial implementation?
I am not sure I am following you entirely. It would be helpful if you would define what exactly you mean by "facilitator" and "worker" in the beginning of the ticket.
It could also check things like: is the gas limit even realistic? If too low: pick up anyway?
Agreed, however a lot of thought should be put into what that actually means.
Agreed. This point and the previous point have a strong relation I think 👍
Yes, using a DB with a popular ORM is probably the easiest, most reliable way here. SQLite?
What does that mean? Generate and store?
As stated before, would opt to limit to one pair per facilitator; name them
How does the facilitator identify "pairs"? I.e. how does the facilitator know which origin/auxiliary belong together? Isn't one address/account per chain sufficient?
Do we really need both? It seems HTTP is the only JSON RPC supported by all clients: https://github.com/ethereum/wiki/wiki/JSON-RPC#json-rpc-support
Will a composer be mandatory?
Are you sure? Couldn't that lead to problems if it happens accidentally and it somehow connects to the wrong of multiple nodes?
Not sure what this means. Please elaborate.
I like the proposal 👍 But I want to note that it could come out differently depending on the findings during implementation. This shouldn't be set in stone.
What does that mean?
Woludn't it be sufficient to keep all sub-processes in memory? Wouldn't they die together with the parent process anyways? I wouldn't detach them ...
Which contract? Get that from where? If it is not recorded already, how high are the chances that the facilitator can actually facilitate the request? Again, I think single pair->single facilitator would make things a lot easier.
While this is probably right, I wouldn't define these things ahead of the implementation. Who knows what we are forgetting about here which will become apparent when implementing it.
I.e. any state root in a block later than the block that contains the stake (which was done by the facilitator).
Thank you for the extra effort, however I think these details should be left to the implementer. What do you think?
Thanks for all the effort @deepesh-kn! This is a long read 😅 I think it would be easier to digest if it was split into tickets right away and each ticket would only contain a contained scope of the overall scope. |
Nice detailed epic 👍
I agree with @schemar that we should support multiple facilitator processes as it gives lot of flexibility and robustness. I would also like to add below:
Above architecture 🏗 🏛 is very common paradigm for better scaling and resource ♻️ management. |
I propose mysql here. It's popular, open source and uses InnoDB engine. Specially mysql handles the concurrency aspects better than sqlite3. It also has great community. Please see the comparison here: |
We should also support below commands to gracefully stop and restart the facilitator process:
|
Below solution can be followed:
With the above locking approach a single stake request will be processed by a single worker. |
I agree with @schemar Martin 👍 . I feel there should be separate ticket 🎫 🎟 to handle Facilitation failures or for SIGTERM 🔴. The scope of the work will depend on happy case implementation outcome, as there could be rollback ⛔️ of multiple entities will be needed. |
I think state like |
Worker after locking the stake request can die. So,I think there should be time devoted to process each request. After this time, the staker request will be unlocked and it can be picked by other workers. |
Facilitator (Executable):
The executable must be able to support multiple chains simultaneously.
Support multiple workers (acceptStakeRequest & progressStake) simultaneously. (Q: private keys are held on node, or on client side? A: on the client side, local machine)
Subscribe / Scan
StakeRequested
event.Workers should avoid race on acceptStakeRequest; eg round-robin
Track the gas available for each worker, if the worker gas too low to perform any transaction then it must not do facilitation.
Calculate if the
gasPrice
andgasLimit
should be acceptable to do facilitation. (What's the threshold value? for now, we can use a constant value)It must act as a hunter for any failed facilitation. (Out of scope for now.)
Handle
SIGTERM
gracefully.Should be able to resume facilitation if it was not complete.
It should track the states of each step of facilitation in DB. Update the DB with the latest state e.g REQUESTED, ACCEPTED, PROGRESSED, etc.
Manage hash lock and unlock secret.
config.json :
db_path
: Database file pathchains
: Contains details of all the chains.chain_id
: Actual chain id number.rpc
: RPC end point.ws
: Websocket end point.workers
: Account address that can perform facilitation for the given chaincomposer_address
: Composer contract address for the given chainsupported_gateway_address
: Supported gateway contract address. IfStakeRequested
event will have the gateway address other than specified here, that will be not taken for facilitation.encrypted_accounts
: This are the encrypted account that is generated byweb3.eth.accounts.wallet.add(account);
Here is a reference https://web3js.readthedocs.io/en/1.0/web3-eth-accounts.html#wallet-addPlease note:
composer_address
andsupported_gateway_address
both are provided for the origin chain only. This will be checked to start the event scanner.Proposal:
Commands :
1. Start facilitator :
config_file_path
: This is the path for the config file. If this is not provided then the facilitator will look at the default location.--chains
: This option is used to specify the chain ids that facilitator should facilitate. This will be origin chain ids2. help :
Executable :
When facilitator starts.
./facilitator start
When facilitator gets the
StakeRequested
events.The facilitator will validate the Event data.
The facilitator will check if the gateway is supported.
The facilitator will check the addresses table to get the origin and auxiliary chain pair and addresses related to that.
If the address table does not have any data for the given chain id and gateway pair, then query the contract and get all the addresses and update the table.
Facilitator gets the worker addresses for the origin and auxiliary chain.
Facilitator forks a new worker child process and gets the PID.
Facilitator inserts a new entry in the
stake_requests
table. This includes the stateRequestHash, chain id, gateway address, stake params, worker address of both chains, pid, state .. etc.The worker creates the hash lock and unlock secret. Unlocks the accounts. Performs accept stake request. Updates the
stake_requests
table with the latest state.Worker checks if the latest state root is committed in the auxiliary chain. If it is committed then it proceeds with the facilitator. If it is not committed then it will give a call back to Facilitator and stop the process.
The facilitator can try to resume facilitation in time intervals, or there can be a new child process that can observe the state root commit event from the anchor, and give a call back to the facilitator. The facilitator can resume the facilitation.
On Handle SIGTERM:
Example
Facilitator as a hunter:
There can be one more child process that can act as
Hunter
which keeps looking for stake and mint events. Not in the scope for now.DB proposal:
Please note: This will give a rough idea, the schema can be improved by the implementer.
This executable should resume any pending or failed task when started. To enable this the status of each
StakeRequest
must be persisted. We can use a database to achieve this (e.g: sqlite3).All the child process have the access to read, insert and update contents in the DB.
stake_requests
REQUESTED
ACCEPTED
ACCOUNT_PROVEN
STAKE_INTENT_COMFIRMED
PROGRESS_STAKE
PROGRESS_MINT
COMPLETE
addresses
facilitator.ts
SIGTERM
.scanner.ts
StakeRequested
event is found.worker.ts
password_0xethereumAccountAddress
, that can be used for unlocking.hashLock
andunlockSecret
. Update DB with these values to keep track in case this process dies.Tickets:
Create a new repository. (Done)
Finalize config.json (Review and suggest)
Finalize DB schema. (Review and suggest)
Finalize the enum value for states column in
stake_request
table.Implement DB interaction layer
StakeRequested
event instake_requests
table.stake_requests
.stake_requests
.stake_requests
.stake_requests
.addresses
table.Implement block scanner.
StakeRequested
event is found.SIGTERM
to inform parent process.Add commander:
./facilitator start
and./facilitator --help
following the proposed command
./facilitator start
.config_file_path
is the path for the config file. If this is not provided then the default path is used.--chains <specific_chain_ids>
this options can be used to specify the chains. The config file may have many chains specified, if this option is provided then the facilitator will start the process for this specific chains only. By default, it will start the process for all origin chains.Implement worker. (can mosaic.js facilitator be used?)
SIGTERM
to inform parent process.Implement Facilitator
gasPrice
andgasLimit
is sufficient to perform facilitations.SIGTERM
to inform parent process.Update readme
The text was updated successfully, but these errors were encountered: