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

Address Issue #171: Validate Generated Addresses Against Expected Ones in JS Client Library #184

Closed
wants to merge 25 commits into from

Conversation

landabaso
Copy link
Contributor

This PR aims to address issue #171 by implementing an enhanced validation method in the JavaScript client library. It enables the comparison of the generated wallet addresses with the expected ones, leveraging "@bitcoinerlab/descriptors". Here are the key updates:

  1. Updated package.json to incorporate new dependencies "@bitcoinerlab/descriptors" and "@bitcoinerlab/secp256k1", and the latest version of "bitcoinjs-lib" to "^6.1.3".

  2. Introduced a new test in appClient.test.ts to validate the generated address or throw an error if it doesn't match the expected one.

  3. Made modifications in appClient.ts to integrate new imports. Changes have been made to the AppClient class to use these libraries for address validation. Some previous validations were removed (see below for further discussion).

Note that this PR utilizes "@bitcoinerlab/descriptors" for validation purposes. It offers an effective approximation for validating addresses. You can view the extensive set of tests that bitcoinerlab passes here.

However, it's worth noting that "@bitcoinerlab/descriptors" does not yet support Tapscript yet. As a result, this third-party validation may not be available for certain types of descriptors. The code takes this into account and handles these cases appropriately.

In getWalletAddress, the previous validation method has been replaced with the new approach comparing generated addresses to expected ones using "@bitcoinerlab/descriptors".

Meanwhile, I'd like to discuss the removal of validation in the registerWallet and signPSBT methods of the AppClient class. An alternative approach could be to generate addresses for dummy keys and compare them using the validateAddress method. However, this might be excessive, potentially slow down performance, and there might be other drawbacks I'm not considering. I look forward to your comments on this proposal.

Regarding the versioning in package.json, I've decided not to update the version number. It appears that the version number of the npm package has been synchronized with the version of the entire repository which includes Rust and Python clients as well. This leads to a situation where a fix in TypeScript would have to wait for a new release version of the whole project before it could be submitted to npm.

I look forward to your feedback.

Closes #171.

Copy link
Collaborator

@bigspider bigspider left a comment

Choose a reason for hiding this comment

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

Thanks for the PR, great to be able to validate addresses at least on SegWit!

Few comments to align with the other libraries:

  • The approach I used in the other libraries is to check the address both at the end of get_wallet_address (no performance impact), but also at the end of register_wallet. This could have a slight performance impact, as generating an address is explicit extra work. however, this is probably negligible in practice.
  • validateAddress can completely replace the existing validatePolicy, since both the bugs that are checked are for SegWit miniscript. The containsA helper can also be deleted.

Feel free to bump the package version to 0.2.3, there's no plan to keep the version aligned across clients.

bitcoin_client_js/src/lib/appClient.ts Outdated Show resolved Hide resolved
@landabaso
Copy link
Contributor Author

landabaso commented Jul 19, 2023

  • The approach I used in the other libraries is to check the address both at the end of get_wallet_address (no performance impact), but also at the end of register_wallet.

I just realised that adding the check mentioned above will break the test for registerWallet. See the code for this test here:

  it("can register a miniscript wallet", async () => {
    const walletPolicy = new WalletPolicy(
      "Decaying 3-of-3",
      "wsh(thresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960)))",
      [
        "[76223a6e/48'/1'/0'/2']tpubDE7NQymr4AFtewpAsWtnreyq9ghkzQBXpCZjWLFVRAvnbf7vya2eMTvT2fPapNqL8SuVvLQdbUbMfWLVDCZKnsEBqp6UK93QEzL8Ck23AwF",
        "[f5acc2fd/48'/1'/0'/2']tpubDFAqEGNyad35aBCKUAXbQGDjdVhNueno5ZZVEn3sQbW5ci457gLR7HyTmHBg93oourBssgUxuWz1jX5uhc1qaqFo9VsybY1J5FuedLfm4dK",
      ]
    );

    const automation = JSON.parse(fs.readFileSync('src/__tests__/automations/register_wallet_accept.json').toString());
    await setSpeculosAutomation(transport, automation);

    const [walletId, walletHmac] = await app.registerWallet(walletPolicy);

    expect(walletId).toEqual(walletPolicy.getId());
    expect(walletHmac.length).toEqual(32);
  }, 60000);

It's worth mentioning that the template requires 3 keys, but only 2 keys are provided. Generating an address with an incomplete set of keys isn't feasible. Is this a legitimate policy anyway? If so, how should we approach this circumstance?

EDIT: I decided to add an additional key and have submitted a new commit reflecting this. Please see my most recent message below for an overview of the changes.

@codecov-commenter
Copy link

codecov-commenter commented Jul 20, 2023

Codecov Report

Patch coverage has no change and project coverage change: -0.24 ⚠️

Comparison is base (f292967) 84.50% compared to head (5209994) 84.27%.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #184      +/-   ##
===========================================
- Coverage    84.50%   84.27%   -0.24%     
===========================================
  Files           17       17              
  Lines         2162     2168       +6     
===========================================
  Hits          1827     1827              
- Misses         335      341       +6     
Flag Coverage Δ
unittests 84.27% <ø> (-0.24%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

see 2 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@landabaso
Copy link
Contributor Author

Hi @bigspider , I've made the changes you suggested. Specifically, I've:

  • Bumped the package version to 0.2.3.
  • Added address validation at the end of registerWallet.
  • Completely replaced validatePolicy with validateAddress and removed containsA.
  • Adjusted the code for correctly parsing the <M;N> format - I had initially misunderstood its interpretation. Included a test case using this format for better clarity.
  • Added a random third key to the registerWallet test to avoid the incomplete keys issue explained in my previous comment. Please, confirm this is ok.

Please let me know if you have any additional feedback.

bigspider
bigspider previously approved these changes Jul 24, 2023
Copy link
Collaborator

@bigspider bigspider left a comment

Choose a reason for hiding this comment

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

Well spotted for the incorrect policy!
Fixed in #188, including the defective test.

Only noted a small nit.

Happy to merge it once rebased on the current develop branch, thanks a lot!

// the `a:` fragment.
throw new Error("Please update your Ledger Bitcoin app.")
}
/* Performs any additional check on the genetated address before returning it.*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo in comment: genetated.

Copy link
Contributor Author

@landabaso landabaso Jul 26, 2023

Choose a reason for hiding this comment

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

Oups, it looks like the rebase+commit did not go as expected. Hang on while I figure out how to solve this.
For some reasone there appear a list of old commits I've made in the past. I believe this is wrong. I think it may be better to start a new PR to sort this out (unless this is ok or you know how I can fix it).

… end of registerWallet; validateAddress replaces validatePolicy; bumped package version; correctly deal with <M;N> format (added a test using this format); Fixed incomplete keys in registerWallet test
Revised the key replacement logic in the `validateAddress` function to prevent misinterpretation of key indices. The loop now iterates in reverse order to avoid scenarios where, for example, @10 is mistakenly replaced as @1, leaving an extra 0. This change ensures that the correct keys are replaced when deriving the wallet address.
@landabaso
Copy link
Contributor Author

This PR is being closed because it has been replaced by PR #189 due to issues with a faulty rebase operation. Please refer to PR #189 for the latest changes.

@landabaso landabaso closed this Jul 26, 2023
bigspider added a commit that referenced this pull request Jul 28, 2023
Replace PR #184: Validate Generated Addresses Against Expected Ones in JS Client Library
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.

Compare generated taproot addresses with the expected ones in the JS client library
3 participants