hydra
hydra copied to clipboard
Commit from external wallet
What & 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.
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 a hydra-node
.
Implementation ideas
-
Commit
client input returns a commit draft transaction as a server output - An external wallet can balance & sign the commit draft transaction and submits it
NB: This is also removing the short-cut of "marking" UTXO to distinguish them in the internal Hydra wallet and fueling would be a "simple" send funds to the hydra-node's fuel address (related #553)
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 Init
to save on a round trip?
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?
Maybe this could even be done in one step together with Init to save on a round trip?
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.
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?
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.
Are there any other actions for which a Hydra node needs the external key?
To clarify: External key == payment key owning UTxOs of the user. No, after committing the funds will be owned by the script on L1.
However, there is one open question / thing to consider here:
- The current on-chain protocol enforces that one of the parties' public keys was used to sign the commit transaction (determined by the participation token spent in the commit tx)
- In this design there would still be an internal cardano key identifying the party to the protocol
- The external wallet would not have that key!
- So we might return an already signed (by the internal key) transaction and the wallet just adds the signature to spend the committed output.
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.
It might happen due to transaction size limits that a party needs to commit twice.
@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 1
right now to not run into limits when collecting & opening the Head. We may be able to increase this limit, but the bottleneck is the collectCom
transaction.
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?
two new Client Inputs; One for Fuel and One for Commit
By having the external wallet do the commit, we can separate it completely from the fuel. That means, anything owned by the --cardano-signing-key
given to the hydra-node
will be fuel.
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?
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).
A simpler alternative to this is to have a InteralAddress or similar Client Input that would give you the internal wallet address
We can make this query-able, but wouldn't we have that information available "outside" the hydra-node as we also take the --cardano-signing-key
as an argument?
return balanced transactions
I do agree on this and I think the journey could be:
- User determines what UTxO they want to commit (get's asked by a Hydra client application).
- This might include preparing UTxOs to only include a chosen
Value
to be committed as a single UTxO (current limitation).
- This might include preparing UTxOs to only include a chosen
- User (or client application) sends the
Commit
client input, which does take theUTxO
to be committed as an argument. - The
hydra-node
prepares a commit transaction, signs it with it's--cardano-signing-key
(the actual Hydra Head participant), and returns the balanced transaction. (This is new ) - The external wallet needs to also sign and submit the transaction.
- This is assuming the
UTxO
given was a pubkey address. Making commits from script outputs would require more parmeters to theCommit
client input and I would make this out of scope for now.
- This is assuming the