Skip to content
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

Unify calculation of wallet id for multisig wallets #3275

Merged
merged 10 commits into from
May 19, 2022

Conversation

paweljakubas
Copy link
Contributor

@paweljakubas paweljakubas commented May 13, 2022

  • I have unified how wallet id is calculated in multisig wallets. Basically I wanted to achieve the following:
  1. for a given wallet created from mnemonic and account pubic key (and having the same payment/staking script) we end up with the same wallet id. This is not the case for shelley wallets where wallet id from mnemonic and account public key are different as the first is calculated on pub key of rootK, and the second is calculated based on account public key. I think this is wrong, and for normal wallet account public key should be the source of wallet id calculation! As multisig are not operational yet, I propose to use the unified calculation of wallet id
  2. As we can have situation that for a given account public key we can have many different multisig wallet, I propose to add script(s) imprint to accXPub and after that hash it. thanks to that we could delete a given shared wallet (using wallet id), rather than many shared wallets sharing accXPub, we have distinct differentiation of them.
  3. Why to take imprint from Script Cosigner rather than Script KeyHash? Because we can have pending shared wallet and not completed Script KeyHash value, but we need wallet id even in pending stage as DB is affected and the shared walet already started lifecycle

Comments

Issue Number

adp-1621

@paweljakubas paweljakubas self-assigned this May 13, 2022
@paweljakubas paweljakubas changed the title Paweljakubas/adp 1621/unify wallet Unify calculation of wallet id for multisig wallets May 13, 2022
let walAcctSameOtherScript = getFromResponse id rPostAcctSameOtherScript
let (ApiSharedWallet (Right walAcctSameOtherScriptActive)) = walAcctSameOtherScript

(walAcctSameOtherScriptActive ^. #id) `shouldNotBe` (walActive ^. #id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test became quite lengthy and not easy to follow... If I'm reading it correctly the ids are not the same because of different templates (active_from:120) vs. (active_from:100)?

Maybe it would make sense to separate this test into two separate ones? One verifying the case with the same ids and the other verifying the case with different ids...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, the same accXPub but difference in any script should give rise to different wallet id. I wanted to add those expectations under already present test to avoid consuming faucet. But we can separate it 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those tests should not consume faucet as no coins are involved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, Piotr, constructed dedicated test just for you ;-)

@piotr-iohk
Copy link
Contributor

for a given wallet created from mnemonic and account pubic key (and having the same payment/staking script) we end up with the same wallet id. This is not the case for shelley wallets where wallet id from mnemonic and account public key are different as the first is calculated on pub key of rootK, and the second is calculated based on account public key. I think this is wrong, and for normal wallet account public key should be the source of wallet id calculation! As multisig are not operational yet, I propose to use the unified calculation of wallet id

I wonder what might have been motivation for different wallet ids in those circumstances in Shelley wallets though... Wallets from accPubKey are mainly for use with HW device and I'm wondering is there any circumstance that makes it actually desirable to be like that. I'm wondering because there is a specific integration test that verifies this in case of Shelley wallets: https://github.com/input-output-hk/cardano-wallet/blob/master/lib/core-integration/src/Test/Integration/Scenario/API/Shelley/HWWallets.hs#L322-L347

Also question what should be the correct way of calculating wallet id... should account public key be source of it? What if we want a multi-account wallet 🤔

@paweljakubas
Copy link
Contributor Author

paweljakubas commented May 13, 2022

@piotr-iohk in shelley wallets we are, at this moment, assuming account ix=0, and in case of the same wallet from mnemonic (here account ix=0), and wallet from account public key that has the same accXPub as the wallet from mnemonic they have different wallet ids. I think this is wrong. For shelley wallets the difference should stem from different account public keys. This will be crucial if we want to support multi-account support. Why? because for any account and the same mnemonic we will have the same wallet id. Which will have consequences, as wallet id is used to pinpoint the resource, so when you delete wallet with a given wallet id you will erase ALL accounts for a given mnemonic. And I am pretty sure we don't want this. Etc Etc

@paweljakubas
Copy link
Contributor Author

BUT, this PR tackles multisig wallets only. And I intend to do it right for multisig wallets as we don't have to deal with backward compatibility. Also for multisig wallets accXPub is not enough to define wallet id. Scripts should be taken into consideration as we have 1-to-many relation in (accXPub - scripr possibilities)

hash $
(unXPub . getRawKey $ accXPub) <>
toByteString pTemplate <>
maybe mempty toByteString dTemplateM
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we need to put here not mempty but cosigner#0 as we expect in that case multisig wallet to just delegate using accXPubIx/2/0 where accXPubIx stems from ix of multisig wallet...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it needs to be changed. otherwise the following two wallets will give different wallet id, although they are the same:

  1. accXPub, spending: something
  2. accXPub, spending: something, staking: cosigner#0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and I adopted already this approach in IntersectMBO/cardano-addresses#185 which should be consistent with what cardano-wallet gives

Copy link
Member

@Anviking Anviking May 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it needs to be changed. otherwise the following two wallets will give different wallet id, although they are the same:

accXPub, spending: something
accXPub, spending: something, staking: cosigner#0

Asking as a someone pretty unfamiliar with multi-sig: does this mean you could create "Multi-sig wallet 1" using account 0 and anyOf [self, Alice] as payment script, and then "Multi-sig wallet 2" using account 0 and anyOf [self, Alice, Bob] and have those be completely separate wallets despite using the same account for payment keys?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, is there a place where I can read about the intended user workflow for multi-sig? I saw you write "spawn multisig wallet with ix=2" elsewhere, so take it's intended that you're adding accounts to the same mnemonic / root key, but maybe there's a place to read about it to get the full picture

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it needs to be changed. otherwise the following two wallets will give different wallet id, although they are the same:

accXPub, spending: something
accXPub, spending: something, staking: cosigner#0

Are you sure, Pawel? 🤔 I suppose that this depends on what exactly the meaning of Nothing for dTemplateM is. It's perfectly conceivable that these cases are actually:

  1. accXPub, spending: something, staking: none (i.e. enterprise address)
  2. accXPub, spending: something, staking: cosigner#0

In other words, if there is no script template for delegation, then the wallet only contains enterprise addresses / addresses that do not have a staking part.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, you are right @HeinrichApfelmus . If we want enterprise addresses to be supported in multisig then we need to allow empty delegation !!!
I will revert commit.
@Anviking Indeed, same accXPub and different script is different entity, having separate address space, and should be identified separately IMHO

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. Just for reference: The multi-signature SharedKey does indeed create enterprise addresses when the staking template is empty:

Address $ case dTemplate of
    Just dTemplate' ->
        createBaseAddress pScript (dScript dTemplate')
    Nothing ->
        createEnterpriseAddress pScript

@HeinrichApfelmus
Copy link
Contributor

Preliminary comments:

  1. I agree, both on avoiding a dependence on the private key, and on keeping backwards compatibility.
  2. and 3. The walletId has both internal use (database) and external use (software that uses the REST API to manage wallets). Which uses do we primarily want to satisfy here? (I agree with 2. and 3. for internal use.)

Observation: For Shelley wallets, the design is very nice in that wallet can always be restored from a single mnemonic. This cannot be the case for multi-signature wallets anymore, as the signatures by other parties are not part of the wallet.

@paweljakubas paweljakubas force-pushed the paweljakubas/adp-1621/unify-wallet-id branch from 3fcf4b4 to fe2a42e Compare May 17, 2022 13:36
@paweljakubas
Copy link
Contributor Author

@HeinrichApfelmus one needs (a) mnemonic, (b) account ix and (c) scripts to be able to reconstruct multisig wallet. Usually (if it contains other cosigner in any script) it will need accXPub of all cosigners engaged to be in ACTIVE state. Only then it can discover its resources, eg. addresses.

Hence, for multi-party multisig wallet coordination servers will play its role, also for the task of restoration.

But that is the nature of multi-signature wallets. It collects extended public keys from parties (via PATCHing), which are used for further derivation of keys (hence extended is required), then parties deliver witnesses to tx via PATCHing to get from partially-signed tx to fully-signed tx.

@paweljakubas paweljakubas force-pushed the paweljakubas/adp-1621/unify-wallet-id branch from fe2a42e to 561c14b Compare May 17, 2022 14:17
toByteString pTemplate <>
maybe mempty toByteString dTemplateM
where
toByteString (ScriptTemplate _ script) =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented on cardano-addresses: The use of show makes it more difficult for non-Haskell code to construct wallet IDs. I propose to export

serializeScriptTemplate :: Script Cosigner -> ByteString

from cardano-addresses and then use it here.

… Later, after version bumps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reused bits from cardano-addresses

@paweljakubas paweljakubas force-pushed the paweljakubas/adp-1621/unify-wallet-id branch from 561c14b to fe2d896 Compare May 19, 2022 10:06
@paweljakubas
Copy link
Contributor Author

bors r+

iohk-bors bot added a commit that referenced this pull request May 19, 2022
3275: Unify calculation of wallet id for multisig wallets r=paweljakubas a=paweljakubas

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- [x] I have unified how wallet id is calculated in multisig wallets. Basically I wanted to achieve the following:
1. for a given wallet created from mnemonic and account pubic key (and having the same payment/staking script) we end up with the same wallet id. This is not the case for shelley wallets where wallet id from mnemonic and account public key are different as the first is calculated on pub key of rootK, and the second is calculated based on account public key. I think this is wrong, and for normal wallet account public key should be the source of wallet id calculation! As multisig are not operational yet, I propose to use the unified calculation of wallet id 
2. As we can have situation that for a given account public key we can have many different multisig wallet, I propose to add script(s) imprint to accXPub and after that hash it. thanks to that we could delete a given shared wallet (using wallet id), rather than many shared wallets sharing accXPub, we have distinct differentiation of them. 
3. Why to take imprint from Script Cosigner rather than Script KeyHash? Because we can have pending shared wallet and not completed Script KeyHash value, but we need wallet id even in pending stage as DB is affected and the shared walet already started lifecycle

### Comments

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number
adp-1621
<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Pawel Jakubas <jakubas.pawel@gmail.com>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented May 19, 2022

Build failed:

@paweljakubas
Copy link
Contributor Author

bors r+

iohk-bors bot added a commit that referenced this pull request May 19, 2022
3275: Unify calculation of wallet id for multisig wallets r=paweljakubas a=paweljakubas

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- [x] I have unified how wallet id is calculated in multisig wallets. Basically I wanted to achieve the following:
1. for a given wallet created from mnemonic and account pubic key (and having the same payment/staking script) we end up with the same wallet id. This is not the case for shelley wallets where wallet id from mnemonic and account public key are different as the first is calculated on pub key of rootK, and the second is calculated based on account public key. I think this is wrong, and for normal wallet account public key should be the source of wallet id calculation! As multisig are not operational yet, I propose to use the unified calculation of wallet id 
2. As we can have situation that for a given account public key we can have many different multisig wallet, I propose to add script(s) imprint to accXPub and after that hash it. thanks to that we could delete a given shared wallet (using wallet id), rather than many shared wallets sharing accXPub, we have distinct differentiation of them. 
3. Why to take imprint from Script Cosigner rather than Script KeyHash? Because we can have pending shared wallet and not completed Script KeyHash value, but we need wallet id even in pending stage as DB is affected and the shared walet already started lifecycle

### Comments

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number
adp-1621
<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Pawel Jakubas <jakubas.pawel@gmail.com>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented May 19, 2022

Build failed:

@paweljakubas
Copy link
Contributor Author

bors r+

iohk-bors bot added a commit that referenced this pull request May 19, 2022
3275: Unify calculation of wallet id for multisig wallets r=paweljakubas a=paweljakubas

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- [x] I have unified how wallet id is calculated in multisig wallets. Basically I wanted to achieve the following:
1. for a given wallet created from mnemonic and account pubic key (and having the same payment/staking script) we end up with the same wallet id. This is not the case for shelley wallets where wallet id from mnemonic and account public key are different as the first is calculated on pub key of rootK, and the second is calculated based on account public key. I think this is wrong, and for normal wallet account public key should be the source of wallet id calculation! As multisig are not operational yet, I propose to use the unified calculation of wallet id 
2. As we can have situation that for a given account public key we can have many different multisig wallet, I propose to add script(s) imprint to accXPub and after that hash it. thanks to that we could delete a given shared wallet (using wallet id), rather than many shared wallets sharing accXPub, we have distinct differentiation of them. 
3. Why to take imprint from Script Cosigner rather than Script KeyHash? Because we can have pending shared wallet and not completed Script KeyHash value, but we need wallet id even in pending stage as DB is affected and the shared walet already started lifecycle

### Comments

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number
adp-1621
<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Pawel Jakubas <jakubas.pawel@gmail.com>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented May 19, 2022

Build failed:

@paweljakubas
Copy link
Contributor Author

bors retry

iohk-bors bot added a commit that referenced this pull request May 19, 2022
3275: Unify calculation of wallet id for multisig wallets r=paweljakubas a=paweljakubas

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- [x] I have unified how wallet id is calculated in multisig wallets. Basically I wanted to achieve the following:
1. for a given wallet created from mnemonic and account pubic key (and having the same payment/staking script) we end up with the same wallet id. This is not the case for shelley wallets where wallet id from mnemonic and account public key are different as the first is calculated on pub key of rootK, and the second is calculated based on account public key. I think this is wrong, and for normal wallet account public key should be the source of wallet id calculation! As multisig are not operational yet, I propose to use the unified calculation of wallet id 
2. As we can have situation that for a given account public key we can have many different multisig wallet, I propose to add script(s) imprint to accXPub and after that hash it. thanks to that we could delete a given shared wallet (using wallet id), rather than many shared wallets sharing accXPub, we have distinct differentiation of them. 
3. Why to take imprint from Script Cosigner rather than Script KeyHash? Because we can have pending shared wallet and not completed Script KeyHash value, but we need wallet id even in pending stage as DB is affected and the shared walet already started lifecycle

### Comments

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number
adp-1621
<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Pawel Jakubas <jakubas.pawel@gmail.com>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented May 19, 2022

Build failed:

@paweljakubas
Copy link
Contributor Author

bors retry

iohk-bors bot added a commit that referenced this pull request May 19, 2022
3275: Unify calculation of wallet id for multisig wallets r=paweljakubas a=paweljakubas

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- [x] I have unified how wallet id is calculated in multisig wallets. Basically I wanted to achieve the following:
1. for a given wallet created from mnemonic and account pubic key (and having the same payment/staking script) we end up with the same wallet id. This is not the case for shelley wallets where wallet id from mnemonic and account public key are different as the first is calculated on pub key of rootK, and the second is calculated based on account public key. I think this is wrong, and for normal wallet account public key should be the source of wallet id calculation! As multisig are not operational yet, I propose to use the unified calculation of wallet id 
2. As we can have situation that for a given account public key we can have many different multisig wallet, I propose to add script(s) imprint to accXPub and after that hash it. thanks to that we could delete a given shared wallet (using wallet id), rather than many shared wallets sharing accXPub, we have distinct differentiation of them. 
3. Why to take imprint from Script Cosigner rather than Script KeyHash? Because we can have pending shared wallet and not completed Script KeyHash value, but we need wallet id even in pending stage as DB is affected and the shared walet already started lifecycle

### Comments

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number
adp-1621
<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Pawel Jakubas <jakubas.pawel@gmail.com>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented May 19, 2022

Build failed:

@paweljakubas
Copy link
Contributor Author

bors retry

@iohk-bors
Copy link
Contributor

iohk-bors bot commented May 19, 2022

Build succeeded:

@iohk-bors iohk-bors bot merged commit 11ab4fe into master May 19, 2022
@iohk-bors iohk-bors bot deleted the paweljakubas/adp-1621/unify-wallet-id branch May 19, 2022 19:19
WilliamKingNoel-Bot pushed a commit that referenced this pull request May 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants