vacuumlabs/cardano-hw-cli

poolRegistration with multiple certificates is not supported

Closed this issue · 13 comments

cardano-hw-cli shelley transaction witness --testnet-magic 3 --tx-body-file /tmp/launchpadpool.txbody --hw-signing-file ledger-red.staking.hwsfile --out-file /dev/stdout
Error: Multiple pool registration certificates found, expected one

Following the good practice from the early cardano-cli poolRegistration days the registration not only includes the poolRegistration.cert itself, but also the owner-delegation certificates. Cardano-hw-cli and the ledger fw must handle such multi certificate witnesses.

Ledger and Trezor hardware wallets currently support only stake pool registration signing by the owners of the stake pool. Other certificates cannot be signed within the same transaction due to security considerations outlined in ledgerjs docs: https://github.com/vacuumlabs/ledgerjs-cardano-shelley/blob/pool-registration-docs/docs/certificates.md#stake-pool-registration-as-an-owner-limitations

basically the problem is that a single witness in the transaction implicitly applies for all entries in the transaction witnessable by that key (e.g. other certificates/withdrawals). So as a precaution against the owners being tricked into signing an operation they don't mean to sign within the stake pool registration transaction, the format of transactions signable by Ledger is restricted to only contain the stake pool registration certificate as stated in the docs above. This should be made more clear also in hw cli docs indeed, and will be linked once ledger docs are updated (the docs above are a PR yet) and it's a limitation that cannot by bypassed at the cardano-hw-cli level as it's part of Ledger Cardano app's logic.

So in general, it may be a good practice to include the delegation certificates (to save some fees or to get additional assurance the owners are actually delegating, though it's not really an assurance as the owners can revoke their stake right afterward on their own anyway), but for hardware wallets this transaction pattern is connected with issues when it comes to guaranteeing to the stake pool owners that what the hw wallet shows them as the effect of the transaction is the actual effect on them and nothing else.

Thanks for the answer, ok so this stays in conflict with the examples and guides we used in the past from IOG. So basically all the owner delegations have to be done after the pool registration and not within one transaction.

But, its still possible to have multiple owners in the pool registration right?

Because i am getting an error trying this, but this may be related to the ledger firmware currently.

I also tried to generate a witness for a poolRegistration (only the poolRegistration certificate in the txBody) for a two owner pool and tried to pay with the ledger for it, i got the following error trying to generate the witness:

Error: Unexpected payment hardware signing file with pool registration certificate found

So, is it not possible to pay with the ledger for a poolRegistration where the ledger is not also an owner? Or can the ledger not be used in paying for a poolRegistration at all? Thx!

@gitmachtl - yes, it's in conflict with the cardano-cli based tutorials which do not take the hardware-wallet specifics into account, here are the hw cli-specific docs to follow: https://github.com/vacuumlabs/cardano-hw-cli/blob/develop/docs/poolRegistration.md

Yes, you can have multiple owners in the transaction, but only one at a time can sign the transaction (as explained in https://github.com/vacuumlabs/ledgerjs-cardano-shelley/blob/pool-registration-docs/docs/certificates.md#stake-pool-registration-as-an-owner-limitations) - the hw wallet won't let you sign on behalf of multiple owners at the same time, again for security reasons (as a usability/security tradeoff there needs to be a hard limit for witnesses exported from the hw wallet when signing a stake pool registration transaction and it's plausible one owner = one hw wallet and if not, you can always just sign the stake pool registration transaction providing a different staking hw signing key each time)

Regarding the payment - that is not supported by hw wallets for stake pool registration for security reasons as explained in #28 - a recommended way around this is creating an address in cardano-cli and sending the exact funds required for the stake pool registration transaction there - that way no significant amount of funds would be at risk of getting lost to a man-in-the-middle attack

ok, i have to write me a spreadsheet whats allowed and whats not, it is getting a bit confusing working with hardware-wallets... :-)

yes its no problem at all working with a small operator wallet, thats also the suggested way. i just needed confirmation that its not possible via ledger. so maybe its easier to get a list whats allowed to pay from a hardware-wallet? a transaction from the hardware-wallet itself to another address of course. registering the own staking address on the chain from the funds of the hardware-wallet itself is also working.

is a hardware-wallet account allowed as a rewards account?

Scenario1: cli owner(s) in the pool, hardware-wallet stakeaccount is only rewards-account
Scenario2: cli owner(s), hardware-wallet owners in the pool, another hardware-wallet stakeaccount is only rewards-account
Scenario3: a combination of cli and hardware-wallet owners in the pool, one of the hardware-wallet owners is also rewards-account

There are special restrictions only for the stake pool registration transactions, really - this stems from the fact that it's a multi-party transaction which alters the standard trust model under which the hw wallet operates, so special precautions needed to be taken.

As long as the transaction concerns a single logical party (sending funds somewhere, a withdrawal, staking key registration/deregistration, even combinations of those "single-party" operations) - that works with the hw wallet without any "gotchas" - you just need to make sure to provide keys to witness all entries, otherwise it becomes basically a "multi-party" transaction which the hw wallet's security policies (or even cardano-hw-cli validation itself) would reject.

Yes, a hw wallet account is allowed as a rewards account, this is also mentioned in the docs: https://github.com/vacuumlabs/cardano-hw-cli/blob/develop/docs/poolRegistration.md#create-reward-address Basically, you just include the given rewards account in the stake pool registration transaction and you can subsequently perform withdrawals as you would in case of an ordinary delegation.

thx, i will try and error. just wanna bring my operator scripts to hardware-wallet support...
https://github.com/gitmachtl/scripts/tree/master/cardano/mainnet

you are welcome, thanks a lot for your questions and feedback as well

also, not sure what version of the Ledger Cardano app you are using, but the 2.1.0 AFAIK was not launched yet and previous versions do not support stake pool registration, here is a related issue where I commented on it with guidance on how to build the new ledger app ahead of the launch, if you want: #17 (comment)

thx, will give it a try. short off topic question, is it safe to share the *.hwsfile with another user?

you are welcome. Respective to the .vkey file, the .hwskey file contains the derivation path of the key and the chaincode of the public key (usable for deriving child keys) - so if you share it with somebody, they cannot sign transactions on your behalf/steal your funds (unless they have a hw wallet initialized with the same seed, of course).

But there may be privacy implications stemming from the fact that the chain code will allow them to derive subsequent non-hardened child keys from the key you shared with them. This is not really an issue for an address-level key (derivation path in the form of 1852'/1815'/<account_number>/chain/address_index'), however for account-level keys (derivation path of the form 1852'/1815'/<account_number>') this means they would effectively know what addresses you have in your account and hence they would be able to tell your full balance.

So to conclude, sharing *.hwsfile does not endanger your funds and as long as you share only address-level *.hwskeys you should be fine also privacy-wise, but still, unless really needed it's more sensible to share only the *.vkey which should be already enough for the counterparty to assemble the transaction. After all, the *.hwskey is useless without the hardware wallet and seed it was generated from. Or did you find a use-case to share the *.hwskey?

Or did you find a use-case to share the *.hwskey?

Well, i try to keep working with hardware-wallets as simple as with the cli ones for the SPOs. The only thing to check if an address is a cli one or a hardware-wallet one is currently to search for the .skey or the .hwsfile for the given name. Because the vkeys are identical and you can't figure out if this vkey is associated with a cli or a hardware skey.

Maybe a solution would be to add a key in the vkey telling that this is a hardware-wallet key? But i am not sure if the cardano-cli and your cardano-hw-cli would be happy with an additional key in the vkey json? is the description field a user definable field or has the content follow some rules?

Like changing it to "Payment Hardware Verification Key" and "Stake Hardware Verification Key" to be in line with your description in your .hwsfile(s)

I wanna automate how to handle stakepool registrations, because right now i and andrew (jormanager) are doing it in a single beautiful transaction (stakepool registration certificate and poolowner(s) delegation certificates). This is not working with hardware-wallets involved, so i have to find a way to find out if a hardware-wallet is involved as an owner or rewards account, because we wanna keep the "simplicity" of using just one transaction for only cli based addresses.