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

Fix None derivation path index for custom currencies #464

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

vnprc
Copy link
Contributor

@vnprc vnprc commented Nov 20, 2024

Description

You can't actually start a mint using a custom currency unit. It panics with Error:UnsupportedUnit. The failure starts in Mint::new when it retrieves a None derivation path.

This PR attempts to fix the issue by requiring the derivation path to be specified when CurrencyUnit::Custom is instantiated. Any u32 derivation path will be accepted except 0-3 which are already allocated to the 4 original currencies.

When converting CurrencyUnit to a string and back it appends the derivation path after the currency string with a colon like in this example: ZUKBUX:12345. There is probably room to improve this. For example we could add a new function to differentiate the full string from just the currency string. I'm open to ideas.

I added unit tests for the new functionality.


Notes to the reviewers

I considered creating a deterministic derivation path by hashing the currency string. This could be cool but it would be inflexible and non-standard. I went with a user-defined approach instead.


Suggested CHANGELOG Updates

CHANGED

  • CurrencyUnit::Custom now requires a derivation path index u32
  • CurrencyUnit::derivation_index() now returns u32 instead of Option<u32>
  • Display now includes a colon and the derivation path index at the end of the string
  • FromStr expects to read the derivation path index in the same format

ADDED

tests for new functionality

REMOVED

FIXED

Mint::new() no longer fails if you specify a custom currency


Checklist

You can't currently run a mint using a custom currency unit
because it throws Error::UnsupportedUnit when getting the
derivation path in Mint::new.

This fix allows the creator of a custom CurrencyUnit to specify
the derivation path.

It formats these custom currency units into strings like UNIT:PATH
where UNIT is the currency name string and PATH is the derivation
path int.
derivation paths 0-3 are already assigned
unit test this behavior
also add a unit test for derivation_path_from_unit
which was where the custom currency bug manifested
@vnprc vnprc changed the title Fix None derivation path for custom currencies Fix None derivation path index for custom currencies Nov 20, 2024
Copy link
Collaborator

@thesimplekid thesimplekid 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 is this an area of the code base I think needs some improvement. However, we can't create our own encoding for custom units with their paths as other implementations will not be able to handle them and we will not be able to handle units from other implementations that don't include the derivation path in the unit.

You can start a Mint with a custom unit you just also have to include the derivation path. Though I don't love this solution as failing to do so created the runtime error you've run into. So we should Improve it.

See this example in Athenut mint

When the Mint is created it first checked the passed custom derivation paths to see if one is included for that unit, if it is not is trys to get one of the standard paths, if it is a custom unit it will panic at this point. See here

@davidcaseria and I discussed using the hashing method you bring up and it maybe a good option, I haven't come up with a better one hence this ugly user defined method. The current derivation paths used for the "standard" units isn't actually defined in spec i just copied them from nutshell. I'm not sure if its something that should be defined or left to implementations, worth further discussion.

@@ -374,45 +374,69 @@ pub enum CurrencyUnit {
/// Euro
Eur,
/// Custom currency unit
Custom(String),
Custom(String, u32),
Copy link
Collaborator

Choose a reason for hiding this comment

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

This would lead to the derivation path being included in the token I believe.

Copy link
Contributor Author

@vnprc vnprc Nov 20, 2024

Choose a reason for hiding this comment

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

Do you mean in the ecash token? Is this a problem?

edit: guessing it's a problem because it's not in the spec so other mints using other implementations will not know how to handle these tokens

Copy link
Collaborator

Choose a reason for hiding this comment

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

Since the serialize/deserialize implementation just use to/from string internally and this modifies those to include or expect the derivation path when the token (cashuB...) get serialized/desrialized it would include or expect the path.

Comment on lines +411 to +415
// Split on ':' to check for derivation index
let parts: Vec<&str> = value.split(':').collect();
let currency = parts[0].to_uppercase();

match currency.as_str() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can't assume that we get the unit in this form it is not in the spec.

if you specify an index over 2^31-1 you get an error from bip32.rs
this change throws the error when creating CurrencyUnit
it also adds more test cases and cleans up some test code
@vnprc
Copy link
Contributor Author

vnprc commented Nov 20, 2024

Thanks for the feedback. I'll code up the hash-based solution to see what it looks like.

@vnprc vnprc marked this pull request as draft November 21, 2024 21:20
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.

2 participants