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

Make notes per denomination targeted by client configurable #3305

Open
elsirion opened this issue Sep 28, 2023 · 3 comments
Open

Make notes per denomination targeted by client configurable #3305

elsirion opened this issue Sep 28, 2023 · 3 comments
Assignees

Comments

@elsirion
Copy link
Contributor

The client always tries to have a specific minimum number of e-cash notes per denomination before issuing notes of the next bigger denomination. This target determines how many out-of-band spends can happen consecutively without the client coming back online.

Currently this target is hard-coded to 2, but should be configurable:

async fn create_exact_output(
&self,
dbtx: &mut ModuleDatabaseTransaction<'_>,
operation_id: OperationId,
amount: Amount,
) -> ClientOutput<MintOutput, MintClientStateMachines> {
// FIXME: don't hardcode notes per denomination
self.create_output(dbtx, operation_id, 2, amount).await
}

But for this to work with the server we also need to make max_notes_per_denomination configurable which is currently always set to 3:

pub const DEFAULT_MAX_NOTES_PER_DENOMINATION: u16 = 3;

max_notes_per_denomination: DEFAULT_MAX_NOTES_PER_DENOMINATION,

Afaik max_notes_per_denomination has to be target_per_denomination denomination_base - 1. Currently we use base 2, so max_notes_per_denomination = target_per_denomination 1, but to be future-proof and keep supporting arbitrary bases we should probably infer the base by looking at the second denomination (=base^1).

@tvolk131
Copy link
Member

tvolk131 commented Oct 2, 2023

If no one else has started on this, I can give it a shot!

@justinmoon
Copy link
Contributor

Go for it

@tvolk131
Copy link
Member

tvolk131 commented Oct 3, 2023

Afaik max_notes_per_denomination has to be target_per_denomination denomination_base - 1

If I understand correctly, the issue here is that we want to have enough notes of every denomination to be able to make target_per_denomination number of offline payments, each of potentially any size. For each offline payment, the worst case is that we need a number of notes for a single denomination that is one less than the base, so we're unable to use the next biggest denomination. For example, a base-2 payment of 1111 (or 15 in base-10) sats that's one away from being rounded up to 10000 (or 16 in base-10), or a base-10 payment of 999 sats that's one away from being rounded up to 1000. For base-2, our worst-case is 2-1=1 note per denomination per payment. For base-10, our worst-case is 10-1=9 notes per denomination per payment.

This sets the floor for the number of notes per denomination to target_per_denomination * (denomination_base - 1). However, we need to account for potential change notes to calculate the ceiling. Each denomination may have up to denomination_base - 1 notes as change due to having a total amount of ECash that can't be evenly broken into the denomination buckets.

So I think max_notes_per_denomination instead is (target_per_denomination * (denomination_base - 1)) (denomination_base - 1) where the first section accounts for offline payments and the second section accounts for change. This can be simplified to the following:

(target_per_denomination 1) * (denomination_base - 1)

Where the 1 accounts for change and the - 1 gives us the maximum value before moving to a bigger denomination (the largest digit in base-10 is 9, which is 10-1).

Does that sound correct?

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

No branches or pull requests

3 participants