massa icon indicating copy to clipboard operation
massa copied to clipboard

A jsonRPC proposal

Open hicaru opened this issue 3 years ago • 9 comments

A jsonRPC proposal.

Abstract.

API endpoint "get_addresses" has an issue, with number format, this proposal must solve this problem, the jsonRPC returns balance in decimals values, this proposal suggest uint numbers.

problem:

The main problem this parameters number format it returns for example: 0.000000003 but should be 3.

On Client we need just use decimals 3 / 10**9 = 0.000000003.

The proposals suggests changing this format to standard like bitcoin, solana, ethereum and all others simular blokcchains.

examples:

current response:

{
    "address": "A1muhtTqVkpzDJgwASYGya9XaY1GmVYfNeJwpobdmtDACTRTBpW",
    "block_draws": [],
    "blocks_created": [],
    "candidate_balance_info": null,
    "candidate_datastore_keys": [],
    "endorsement_draws": [],
    "final_balance_info": null,
    "final_datastore_keys": [],
    "involved_in_endorsements": [],
    "involved_in_operations": [
        "WBvQvZiVduvG7RpqK9ei8DFBqYKEUpRLpjonnYPVgoR6x7bps",
        "QYAZKBjDoza3H1PuitxEMttkKTXcibSy4AKY8Qmf4Zh8syAah",
        "2cVAfxLMyPS7RdN9GNiJxisLiei4srTtAspjNwjcNAPEUDykYk",
        "2oCqomPuuxJms9TZjgoiYkY3HSCFoajXnVAyfSKXBFX1sPSvSB"
    ],
    "ledger_info": {
        "candidate_ledger_info": {
            "balance": "0.000000003"
        },
        "final_ledger_info": {
            "balance": "0.000000003"
        },
        "locked_balance": "0"
    },
    "production_stats": [
        {
            "cycle": 0,
            "is_final": false,
            "nok_count": 0,
            "ok_count": 0
        }
    ],
    "rolls": {
        "active_rolls": 0,
        "candidate_rolls": 0,
        "final_rolls": 0
    },
    "thread": 12
}

After the proposal approved, it will be:

{
    "address": "A1muhtTqVkpzDJgwASYGya9XaY1GmVYfNeJwpobdmtDACTRTBpW",
    "block_draws": [],
    "blocks_created": [],
    "candidate_balance_info": null,
    "candidate_datastore_keys": [],
    "endorsement_draws": [],
    "final_balance_info": null,
    "final_datastore_keys": [],
    "involved_in_endorsements": [],
    "involved_in_operations": [
        "WBvQvZiVduvG7RpqK9ei8DFBqYKEUpRLpjonnYPVgoR6x7bps",
        "QYAZKBjDoza3H1PuitxEMttkKTXcibSy4AKY8Qmf4Zh8syAah",
        "2cVAfxLMyPS7RdN9GNiJxisLiei4srTtAspjNwjcNAPEUDykYk",
        "2oCqomPuuxJms9TZjgoiYkY3HSCFoajXnVAyfSKXBFX1sPSvSB"
    ],
    "ledger_info": {
        "candidate_ledger_info": {
            "balance": "3"
        },
        "final_ledger_info": {
            "balance": "3"
        },
        "locked_balance": "0"
    },
    "production_stats": [
        {
            "cycle": 0,
            "is_final": false,
            "nok_count": 0,
            "ok_count": 0
        }
    ],
    "rolls": {
        "active_rolls": 0,
        "candidate_rolls": 0,
        "final_rolls": 0
    },
    "thread": 12
}

Reason

All other blockchains are using prime numbers, this will be more friendly for all blockchain and dapps developers.

Solve the compatibility issue with other blokcchains

hicaru avatar Sep 08 '22 10:09 hicaru

I worked with well known payment company and this is the same used format to avoid floating precision issues.

aoudiamoncef avatar Sep 08 '22 10:09 aoudiamoncef

I think that what you want to do is to represent amounts as unsigned integers composed of their mantissa ($10.23 becomes 1023u64). Note that this has nothing to do with prime numbers, those are just normal unsigned integers.

The problem with this solution is extensibility: if at some point we decide to add more precision (say switch to 16 digits after the decimal point), all the programs that use the API will need to be corrected because they will silently overestimate all amounts by a factor 10000000. This is a dangerous situation.

Floating point representations (float, double) are also not a good solution because of the risk of precision loss: https://docs.python.org/3/tutorial/floatingpoint.html

That's why we decided to go for a Decimal representation because:

  • it is extendable: we can change precision in the future without causing silent errors in existing users
  • it has zero precision loss in base 10
  • it has a natural human-readable representation which make sit less error-prone
  • that's the worldwide standard for representing all currencies as text: https://www.dfa.cornell.edu/treasurer/cash-management/processinginternational/intl-currency
  • that's the worldwide standard for representing all currencies in databases: https://dev.mysql.com/doc/refman/8.0/en/fixed-point-types.html
  • every programming language we use has a library for handling Decimal

damip avatar Sep 08 '22 10:09 damip

The standard of the banking industry differs from the standards of blockchain.

hicaru avatar Sep 08 '22 10:09 hicaru

The standard of the banking industry differs from the standards of blockchain.

There is no blockchain standard.

Bitcoin: https://en.bitcoin.it/wiki/Proper_Money_Handling_(JSON-RPC)

Values are expressed as double-precision Numbers in the JSON API, with 1 BTC expressed as 1.00000000 

What we do is basically what bitcoin does, but cleaner and more robust to evolution

damip avatar Sep 08 '22 12:09 damip

The standard of the banking industry differs from the standards of blockchain.

There is no blockchain standard.

Bitcoin: https://en.bitcoin.it/wiki/Proper_Money_Handling_(JSON-RPC)

Values are expressed as double-precision Numbers in the JSON API, with 1 BTC expressed as 1.00000000 

What we do is basically what bitcoin does, but cleaner and more robust to evolution

this is what about proposal, bitcoin jsonRPC returns for example 100000, the app or library should convert it to decimal 100000 / 1e8 = 0.001 BTC. but we now returns already decimals amount

hicaru avatar Sep 08 '22 12:09 hicaru

I think it is a good idea to use integer numbers. If the problem is back compatibility, you can use an additional field.

"ledger_info": { "candidate_ledger_info": { "balance": "0.000000003", "balance_int": "3" }, "final_ledger_info": { "balance": "0.000000003", "balance_int": "3" }, "locked_balance": "0" },

xkotok avatar Sep 08 '22 13:09 xkotok

We could mix both responses, keep the current one and add additional fields for decimal response.

aoudiamoncef avatar Sep 08 '22 14:09 aoudiamoncef

We could mix both responses, keep the current one and add additional fields for decimal response.

Yes, this is a great solution

hicaru avatar Sep 08 '22 14:09 hicaru

I know that for API consumers, It's easier to parse a decimal response with a currency/unit without any unpredictable behavior. This way we have the benefits of classique banking approach and our Massa way which is propagated internally.

aoudiamoncef avatar Sep 08 '22 14:09 aoudiamoncef

The upcoming decimal standard NativeAmount solves this: https://github.com/massalabs/massa-sc-runtime/issues/246

damip avatar Jun 05 '23 09:06 damip