Thought about big numbers

As libre currency have exponential growing number property, we must care about a programming limitation: integer variables types maximum value.

Metab brouzouf experience

With Meta brouzouf, we simulate more than 330 years duration which on average 15 members creating money. Meta brouzouf monetary mass is 64.10¹⁸ MB which is up than a long int which is 2⁶³ - 1 = 9.10¹⁸ units. That’s not the case of UD which is today 0.5 10¹⁸ MB.

uCoin softwares are using int type bigger than long int.

Problem

In a production libre currency, when big numbers could arrived? We know growing rate is about 10% per year. But we don’t know about the number of members.

Simulation

So, I try a simulation, which calculate M and UD.
Hypothesis:

  • monetary mass growth c = +10%/year as recommended by RTM.
  • we consider number of members N constant.
  • Initial UD is 100 units.
  • UD calculation is always calculated with UD = c × M/N

Libre currency - big number simulation.ods (9,6 Ko)
You could change N (number of members).

Conclusion

My conclusion is that 30 years of libre currency duration (Bitcoin is ~7 years duration) with:

  • N = 1.000 members, M go to 1.7 10⁶ MB and UD go to 1.7 10³ MB.
  • N = 1.000.000 members, M go to 1.7 10⁹ and UD go to 1.7 0³ MB.

It’s not a problem for less than 30 years and less than 1 M members. It could be an issue for longer duration and more members.

1 J'aime

Yes, we talked about this during FMM5, and added an issue for this: https://github.com/ucoin-io/ucoin/issues/61

The solution is made up of 2 things:

  • first, we agree to simply forget money issued 160 years ago, because such money (the whole monetary mass of all members at this epoch) represents only $0,01$% of today’s money.
  • secondly, we will represent UD with a rolling value: it will always have 6 digits representation (for example $250.000$), and as soon as UD reaches more than $999.999$, we shift one number and add a power representation somewhere.

Example

Say we have current block:

[...]
Number: 45302
UniversalDividend: 950000
UnitBase: 0
[...]

Then on next UD block (let’s say this block is number 47888), we would have with $c = 10$%:

[...]
Number: 47888
UniversalDividend: 104500
UnitBase: 1
[...]

So we know the absolute value of UD $ = 104500 \times 10^{UnitBase}$, we can make transactions using the same notation of amounts + unit base.

And if we don’t have a power of 10 value for UD, we round at the upper value for UD(t+1). For example if we had

  • UD(t) = 950004 (base 0)

then we have:

  • UD(t+1) = 1045008 (base 0)
  • UD(t+1) = 104501 (base 1)

So what would be written is

[...]
Number: 47888
UniversalDividend: 104501
UnitBase: 1
[...]
2 J'aime

Mmmh OK. To be sure to understand you : When you talk about “forget money”, there isn’t anything which removes money for real ? If I understand correctly the solution, it’s only about the rounding due to the 6 numbers and the unit base ?

We do remove old money: the outputs of 160 years old transactions is purely and simply non-usable. So in the nodes database, the sources of this age are removed.

Now, how do we identify the sources to remove? The UnitBase could be very helpful.

Indeed, the UnitBase increments every 23 years approximately (the monetary mass $M$ grows by 10 times every 23 years with c = 10% as you know). We deduce from this that, passed exactly 160 years, $M$ has grown by $10^{160 / 23} = 10^{6,95}$ times.

So we can consider $7$ incrementations of UnitBase allow us to destroy some money.

For example, let’s say that current UnitBase is 7 and call it CurrentBase. Then any source with UnitBase <= CurrentBase - 7 can be destroyed: the sources refering to UnitBase = 0.

Other example: if CurrentBase is 28, then any source with UnitBase <= 21 can be destroyed.

As a conclusion, we could say that we only keep the last $7$ UnitBase sources, as they are equivalent to money between now and 160 years old.

And a second conclusion, we see that:

  • UD is has a max “value” of 999.999 = 10^6
  • We have a max number of members around 1 million = 10^6
  • We handle at max 7 UnitBase = 10^(7 - 1) (because base 10^0 = 1, so we don’t count it as a power of 10)

So in the end, we have a window of total monetary mass maxed at $10^{3 \times 6} = 10^{18}$. And that’s super cool, because an unsigned integer today can handle a value up to $9 \times 10^{18}$. We are all good :slight_smile:

3 J'aime

Mmmh… Since every time we make a transaction, we generate new sources from old sources, how do you define a source that can be destroyed?

To better understand, here is an extract from UCP I am writing.

The whole point is to understand that transactions refer to UnitBase, just like UniversalDividend does in a given block. And depending on current UnitBase, we can say that sources carrying a UnitBase(t - 7) can be destroyed.


CommonBase

Each input has an InputBase, and each output has an OutputBase. These bases are to be called AmountBase.

The CommonBase is the lowest base value among all AmountBase of the transaction.

For any amount comparison, the respective amounts must be translated into CommonBase using the following rule:

AMOUNT(CommonBase) = AMOUNT(AmountBase) x POW(10, AmountBase - CommonBase)

So if a transaction only carries amounts with the same AmountBase, no conversion is required. But if a transaction carries:

  • input_0 of value 45 with AmountBase = 5
  • input_1 of value 75 with AmountBase = 5
  • output_0 of value 12 with AmountBase = 6

Then the output value has to be converted before being compared:

CommonBase = 5

output_0(5) = output_0(6) x POW(10, 6 - 5)
output_0(5) = output_0(6) x POW(10, 1)
output_0(5) = output_0(6) x 10
output_0(5) = 12 x 10
output_0(5) = 120

input_0(5) = input_0(5)
input_0(5) = 45

input_1(5) = input_1(5)
input_1(5) = 75

The equality of inputs and outputs is then verified because:

output_0(5) = 120
input_0(5) = 45
input_1(5) = 75

output_0(5) = input_0(5) + input_1(5)
120 = 45 + 75
TRUE

Amounts

  • For each UD source, the amount must match the exact targeted UD value
  • The sum of all inputs in CommonBase must equal the sum of all outputs in CommonBase

Consequence: we cannot create money nor lose money through transactions. We can only transfer coins we own.

  • Each output AmountBase must be equal to the maximum AmountBase of all inputs

Consequence: if a transaction carries inputs with a different AmountBase, these coins will be transformed into a higher UnitBase if they make round output amounts for this higher base.


1 J'aime

OK, so this means that only forgotten sources, unused for many many years, will be pruned from the database ?

Yes exactly.

We also have sources from a UnitBase that can merge into a superior UnitBase, so units merging into the upper order of 10.

Edit: note how we cannot move backward between unit bases, so for example a unit 7 cannot split to become a unit 6.

Edit 2: this also means that, if meta_brouzouf was using this system, money after 160 days would no more be usable. So Sakia would not display them.

OK, great, got it :slight_smile:

And what’s your opinion about it? Is there something better to do?

No I think it’s great :

  • Unused transaction for 160 years worths nothing, they can be pruned
  • Unitbase increase is useful to round values and make old money disappear too
    Just a note about rounding value when increasing the UnitBase :

950005 * 1.1 = 104500.5
or
500000 + 500005 = 1000005

So we have a rounding happening here. The chosen rounding should be as neutral as possible on monetary mass, and also should be described in the specification. It should not be implementation-dependant.
I suggest to use bankers rounding

I’ve already chosen not to use any rounding, this is what means:

The sum of all inputs in CommonBase must equal the sum of all outputs in CommonBase

So the merge of one base amounts into another can only happen for multiples of 10: if we have input 16 + 4, base 0, we can have 2, base 1. But 22, base 0, cannot be expressed using base 1.

However, your rule could be used for UD computation. For now I’ve written:

UD(t+1) = CEIL(UD(t+1) / 10)

General ideas seem ok. But there is an important detail to think about. Forgetting money depends also on N (space), not only on time (160 years). If money(t-160) is 0,01% (=1/10000), and there is let’s say N = 10 000 members (or more), then this means that old money (t-160) represents a full M/N single amount of money.

Then, if one member has all that old money in his own account, he has at least M/N. If you remove the old money, then his account will be decreased of M/N, without any justification. And if M/N is a “little quantitiy” compared to M, it is absolutely not “little” for a member, it is a huge one.

So, it would be better to have a rule like : if M(t-x) < UD / 10⁶ (6 = the number of usable digits of current UD), then you can “remove” M(t-x).

With this rule you won’t know exactly the time needed to “remove” old money, but with some simulation you can have an idea of what it could be.

I interprete what you say @Galuel as “we can remove money as soon as its amount is a decimal value compared to current UD unit”, so actually we can remove money whose amount is under 1 UD unit (for example if UD = 123456, we remove money source with value 0,4).

We don’t have decimal values in uCoin, but I use this notation for the sake of demonstration. Instead you can imagine UD = 1234560, and we remove any amount between 1 and 9.

If we compare such amounts to today units with euro, it means that we remove amounts of money that are < 0,01€, for example 0,004€.

That’s what I say with:

So we already take the spatial dimension into account this way.

No this is not correct because M(t-x) is not UD(t-x).

You can have UnitBase(t-x) <= CurrentBase(t) but you can have at the same moment M(t-x) >= UD(t) or even >= M/N(t)

And all that money can be in one unique account.

So no, you cannot refer to UnitBase and CurrentBase only. You need to compare M(t-x) and UD(t) = c*M/N(t) where first is a sum in space of all accounts(t-x), and second is current UD(t).

OK got it.

Anyway I haven’t implemented money destruction yet. I let this to developers of 2048.

3 J'aime

This is correct :relieved:

1 J'aime

C’est un peu le bazar sur le forum, est-ce que ce topic est la version la plus récente de ce sujet ? Ou est-ce que d’autre specs techniques ont émergé depuis ?

Je pense qu’il faut qu’on document la gestion des grands nombres, c’est un aspect important de Duniter. Je cherche déja à compiler toutes les ressources dispersées sur le forum (j’ai déja eu du mal à retrouver celui là…)

1 J'aime