-
Notifications
You must be signed in to change notification settings - Fork 87
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
Commit from external wallet #215
Comments
FWIW, we drew this a long time ago in this use case diagram: |
This feature would be very useful to us for our work on a Hydra Head-as-a-Service platform, for the reasons outlined in the motivation. It would greatly reduce the needed trust in the platform provider and improve robustness :) |
@parenthetical Does sound the implementation idea reasonable to you? As you might have seen we have the Commit API input and this feature would change it's semantics to not actually do commit a UTxO, but return a draft transaction which can be used to do so. Furthermore, do you think it makes sense to keep both ways? i.e. be able to commit something from the hydra-node owned key when we have the ability to do so via any external wallet? |
@ch1bo the API with the draft transaction sounds good to me. Maybe this could even be done in one step together with I can't think of a reason to keep both... Another process could always handle the commits for which the wallet key is needed, right? Are there any other actions for which a Hydra node needs the external key? |
Hm. For the initiator, yes. But for the other parties, this will be a different workflow. Probably not worth it to account for two different workflows, especially in the client application.
Yes. Doing commits only external should be fine. Our end-to-end tests likely would use a cardano client (or the cli) to sign and submit the transaction then.
To clarify: External key == payment key owning UTxOs of the user. However, there is one open question / thing to consider here:
|
To add to this, right now, the committing of UTxO's is conflated with the readiness of the head participants. When all parties added something (it might be an empty utxo) they are marked as ready and the node automatically collects the UTxO's and opens the head. It might happen due to transaction size limits that a party needs to commit twice. Furthermore, after this first commit, it should not be possible for the other parties to collect and open the head, preventing a party to commit more to the head. |
@perturbing Yes, having two commit transactions is not possible right now. It's also not possible in the basic Hydra Head protocol (as specified and implemented right now). We even limit the number of UTxOs to commit to Let's open another issue for doing that. It's a bit orthogonal to this effort here about outsourcing the actual commit transaction creation / submission. |
The way I see it, we need two new Client Inputs; One for Fuel and One for Commit, both would return balanced transactions. The main reason for balanced transactions is that while cardano-wallet exposes an endpoint to balance a transaction, Light Wallets expect to sign balanced transactions. Also I don't know of a Light Wallet that exposes any balancing functionality, nor does a "balance" endpoint exist in the CIP-30 specification. That being said wallets do usually have the ability to balance transactions internally (An example is when doing a simple send), so if balancing ends up being too much to expect the node to do, you could potentially just make it a requirement that you must balance the transaction yourself, this adds a small amount of friction, though we could likely bridge the gap in Hydra Pay. The need for Commit is fairly self explanatory as it was already addressed in the initial proposal; The Fuel Client Input would be a balanced transaction that actually funds the internal wallet of the node. A simpler alternative to this is to have a InteralAddress or similar Client Input that would give you the internal wallet address to build a transaction out of yourself. As for the details of fuel in the internal wallet, how do you envision fuel management from the perspective of the participants managing their node, or the user running the network of nodes for a Head? |
By having the external wallet do the commit, we can separate it completely from the fuel. That means, anything owned by the
Knowing how much fuel a node has is basically just knowing the balance of the internal wallet's address. Refueling is sending more ADA to the internal wallet's address (like now).
We can make this query-able, but wouldn't we have that information available "outside" the hydra-node as we also take the
I do agree on this and I think the journey could be:
|
@ch1bo just to be explicit I think the path you have laid out for commit from external wallet makes sense, and hits the right blend of user experience/functionality. Upon originally reading your response, I exclaimed "That checks out" but didn't actually make that clear in this back and forth, so I figured I would do so now. |
So our (hydra-auction) usecase will not be covered?
What is draft exactly? I guess |
I have drawn a sequence diagram for a potential implementation. The architectural changes are not 100% clear yet, but likely we need new interfaces to the Anyhow, here the draft diagram: sequenceDiagram
Client->>+API: GET /commit + UTxO + redeemers
API->>+QueryHead: getDraft CommitTx
Note left of QueryHead: New interface for <br/>query-only access to Head
QueryHead->>QueryHead: check "can commit" in headState
QueryHead->>QueryHead: getChainState headState
QueryHead->>+Chain: draftTx (chainState, CommitTx)
Note left of Chain: New method for <br/>drafting transactions
Chain->>Chain.State: commit (chainState, args) :: Tx
Chain->>Wallet: balance & sign :: BalancedTx
Chain-->>-QueryHead: BalancedTx
QueryHead-->>-API: BalancedTx
API-->>-Client: BalancedTx
Client->>Client: sign & submit Tx
|
We still need to figure out whether we want to do option A or B:
sequenceDiagram
Client->>+HydraNode: GET /commit + UTxO + datums, scripts, redeemers
HydraNode->>HydraNode: sign Tx
HydraNode-->>-Client: Tx
Client->>Client: sign Tx
Client->>CardanoNode: submit Tx
CardanoNode-->>Client: Success/Fail
sequenceDiagram
Client->>+HydraNode: GET /commit + UTxO
HydraNode-->>-Client: TxBody
Client->>Client: add scripts, data, redeemers, balance & sign Tx
Client->>+HydraNode: POST /commit + Tx
HydraNode->>HydraNode: check Tx & sign Tx
HydraNode->>CardanoNode: submit Tx
CardanoNode-->>HydraNode: Success/Fail
HydraNode-->>-Client: Success/Fail
|
what about a combination of the two?
and then we provide the other endpoint for POST /commit using the drafted TX + optional customization from the client, and we check wether or not this TX require further signing and we submit it :) wdyt? does it makes sense? |
Discussion of today's grooming
Currently we lean towards option A, but we will make sure to check back with you @Yasuke, @uhbif19 and other users. Please chime in :) |
As I said previously, I think option B may be better, because in some cases Hydra client could drop L1 connection completely, and made its configuration simpler. Also I have another concern. I think that client should have some meant to validate transaction sent by Hydra Node. Otherwise it can always send some "transfer me all ADA" transaction for signing. That means that there should be some public API in |
This is also possible with Option A by providing a "just submit to L1" endpoint. It's orthogonal to the two options A and B, which are mostly about how the transaction is built and signed. |
My vote is for Option B. I think it provides more flexibility for different use cases than Option A. However, I would refactor Option B into three distinct endpoints:
Analogous to the self-service (1 + 2) and full-service (1 + 2 + 3) options at gas stations. 😄 |
@GeorgeFlerovsky Unfortunately we cannot do your number 2. due to security reasons, or at least we would not feel very comfortable doing it. It could be used to have the Your option 3. is orthogonal to this feature and might be implemented in any case for convenience. |
@ch1bo In a two-party transaction, there are two distinct roles:
The first signer is inherently in a more secure position because he drafts the transaction, whereas the second signer needs to review a wider surface of unverified information. Regarding external commits in Hydra:
Personally, I think that it is better for the hydra node to be the second signer, because it has a narrower scope of utxos to safeguard against leaks. |
RE |
@ch1bo I guess it's fine for the client to be the second signer, as your current PR implements it. 👍 |
@GeorgeFlerovsky I see and thanks for bringing up this point. It makes Option B, where the Sticking to Option A and the need for the client to check whether the returned transaction does what was intended is yielding more work for the client (= bad UX/DevX) and I already see it coming that 99% of applications running on Hydra would not do this check. |
@Yasuke is on vacation, so I will answer on behalf of him and the hydra-pay team. After discussing the two options internally, we are confident that either solution is workable for us, but we think that Option B is more favorable for the ecosystem. It makes it easier to implement hydra clients, and the UX is somewhat nicer for the end user. |
With option B, one difficulty I can see is that the burden to construct a well-formed commit transaction is now on the client. @GeorgeFlerovsky I now you've done it already in your solution. What's your opinion on the difficulty level to do so? And can you think of things we can provide to the client to ease this process? |
Redirect to @uhbif19, who implemented this in our solution |
Option B as outlined above would return already a blueprint for a commit transaction to the client. However, a client would not know whether this is proper or not. As a first step it would only make sure its balanced (pay the fee), add its witnesses and sign it. To really check whether the returned transaction draft is a sound commit transaction, these steps, as also done by the |
I think that I understood this issue a little bit wrong before. Yes, Option A definitely does not make any sense, cuz client should validate tx then.
But this needs to be supported by Hydra API lib, or it might break on version change. And if it is covered by Hydra lib, why ask server for that? So, AFAIK, there are this parts of this task:
I think that 1 should be returned by hydra-node. Maybe they might just be included in greeting. As for 7 (submiting), I am not sure if it need to be separated |
I think that for some dapp protocols, it would be advantageous for the client to submit and monitor the transaction themselves through their own node. It's useful to have the hydra endpoint for convenience to submit transactions on the clients' behalf, but it should not be mandatory to use it. |
I think that external commits will be used by two types of users:
For the simple case (1), the TxBody returned by For the more complicated case (2), the dapps already need to verify and construct transactions in this way. |
But if they monitor Tx, they would probably like to monitor them all. And other Txs could not be submitted by users.
Why do this instead of creating Tx on client side? |
Why
As a user if I want to commit inside a Head, I would need to send whatever I want to commit first to the internal wallet of my hydra node. This is non-ideal as the funds need to be sent there first and would potentially at a higher risk (of losing the internal signing key) in the transit.
What
This feature should allow users to use an any external wallet to commit funds to a Hydra Head. Which means, any outputs supported by the external wallets can be committed (multi-sig, scripts, withdrawals,..), which are not necessarily supported by the internal wallet!
There will still be an internal wallet for "Hydra fuel" though, but that is only used for funds to "drive" the Hydra Head protocol are in custody of aWe keep the fuel and only remove fuel handling in a separate step.hydra-node
and no fuel "marking" is required anymore (related #553).How
hydra-node
TBD (old)
Commit from scripts not possible this way as redeemers cannot be added after the fact
Does there exist a standard for signing externally?
Would greatly benefit from a request/response query API
The text was updated successfully, but these errors were encountered: