tronprotocol / tips

TRON Improvement Proposals
228 stars 204 forks source link

Dynamic energy model in TRON protocol #491

Closed daniel-cao-byte closed 1 year ago

daniel-cao-byte commented 1 year ago
tip: 491
title: Dynamic energy model in TRON protocol
author: daniel.cao@tron.network
discussions-to: https://github.com/tronprotocol/tips/issues/491
status: Final
type: Standards Track
category: Core
created: 2022-12-19

Simple Summary

This tip proposes a mechanism to perform dynamic regulation of energy in contracts to balance the distribution of energy among contracts.

Abstract

In this tip, we propose a mechanism to dynamically adjust the energy consumption of a contract according to its execution resource usage.

If a contract uses too much CPU resources in one cycle, the energy consumption of that contract will add a percentage as penalty in the next cycle; and when its use of resources is reasonable, the energy consumption of that contract will gradually return to normal. Through this mechanism, we hope to make the distribution of energy resources on the chain more reasonable, and combat low-value or fraudulent transactions while allowing more projects and contracts to have a chance for development.

Motivation

According to Tronscan, more than 85% of the current TRON network's CPU execution time is concentrated on a few contracts. And some of the transactions are low-value or even fraudulent ones.

If this situation persists,

Therefore, we propose to introduce a dynamic energy model to increase the transaction cost of low-value and fraudulent transactions without affecting other dApps, and also to guarantee the robustness, diversity and balanced development of the ecosystem.

Specification

Three main parameters controlled by the proposal are introduced in the scheme, and the meaning of each parameter is as follows,

And there is a derivative parameter for calculation:

The scheme mechanism is as follows.

During each maintenance period, the base energy consumed by the contract execution is recorded. If the contract's base energy consumption exceeds threshold during a maintenance period, then its consumption_factor (1 + factor) will be increased by increase_factor during the next maintenance period, the part that exceeds 1 is the penalty factor of the contract.

Otherwise, it will be scaled down by a decrease_factor until consumption_factor grows to max_factor+1 or drops back to 1. Each contract's instructions will be scaled up by consumption_factor when calculating energy consumption.

When threshold is exceeded in the previous maintenance period:

consumption_factor = min(consumption_factor * (1 + increaese_factor), max_factor+1)

consumption_factor = 1 + factor

factor = min((1 + factor) * (1 + increaese_factor) - 1, max_factor)

Otherwise,

decrease_factor = increaese_factor / 4

consumption_factor = max(consumption_factor * (1 - decrease_factor), 1)

factor = max((1 + factor) * (1 - decrease_factor) - 1, 0)

The energy consumption of a trigger_smart_contract will be:

# assume a trigger involving n contracts, 
# for each contract i,
cost_origin_i = sum(cost_instruction)
cost_penality_i = sum(cost_instruction * factor_i)
cost_i = cost_origin_i + cost_penality_i

# for the entire trigger
cost = sum(cost_1, cost_2, ..., cost_n)

Rationale

Cycle selection

We use a fixed cycle because dynamic cycle selection introduces additional complexity for the chain, and its increased flexibility can basically be supplemented by dynamic adjustment of the threshold. Too short a period tends to make some temporary popular contracts hit the rules and interfere with various dApps to carry out innovative activities; at the same time, the length of the period is best to have a record of the corresponding concept on the chain, reducing unnecessary development and maintenance costs. For all these reasons, we suggest the length of the maintenance period as the statistical cycle of this program.

Effective method

We choose a gradual scaling approach, and when the contract consumes base energy continuously exceeding the threshold, its scaling factor will also be continuously scaled up, which draws on the idea of dynamic adjustment of other mainstream public chains' resources by usage. At the same time, we add the limit of the maximum amplification factor in order to avoid infinite amplification.

Adjustment method

We introduce a factorized scaling of the energy consumed by the execution of a contract instruction. The method correlates with the actual execution of the contract.

Backward Compatibility

There are no backward compatibility issues.

API Changes

There are several API changes involved in this TIP.

  1. Add the contract_state structure in /wallet/getcontractinfo

    {
    "runtimecode": "",
    "smart_contract": {},
    "contract_state": {
    "energy_usage": 2000,
    "energy_factor": 10000,
    "update_cycle": 500
    }
    }

    energy_usage: the origin energy consumption of the contract in current maintenance period. energy_factor: the penalty factor of the contract in current maintenance period, the precision is 10_000, energy_factor = 1000 means the penalty percentage is 10%. update_cycle: the current maintenance period number.

  2. Add energy_penalty in contract trigger results, involving /wallet/triggerconstantcontract and triggersmartcontract

    {
    "...": "...",
    "energy_used": 643,
    "energy_penalty": 200
    }

    energy_penalty: the total penalty energy in the transaction.

  3. Add energy_penalty_total in transaction receipts, involving /wallet/gettransactioninfobyid and /wallet/gettransactionreceiptbyid

/wallet/gettransactioninfobyid

{
    "id": "",
    "blockNumber":,
    "...": "...",
    "receipt":
    {
        "energy_usage": 98115,
        "energy_usage_total": 98115,
        "net_usage": 379,
        "result": "SUCCESS",
        "energy_penalty_total": 5000
    }
}

receipt.energy_penalty_total: the total penalty energy in the transaction.

/wallet/gettransactionreceiptbyid

{
    "Receipt": {
        "result": "SUCCESS",
        "energy_fee": 618400,
        "energy_usage_total": 6184,
        "net_usage": 313,
        "energy_penalty_total": 719
    }
}

Receipt.energy_penalty_total: the total penalty energy in the transaction.

Security Considerations

There are no security considerations.

otakuinny commented 1 year ago

threshold: threshold value of base energy consumption for the contract hit rule

@daniel-cao-byte, no idea what you mean by above. Can you use an example with numbers so we can understand. Also, you do know that the phishing scammers just call the USDT contract directly, right? In this case, the transaction cost of the USDT contract will rise which leads to more expensive usdt transfer costs for everybody. Unless, I misunderstood your proposal.

daniel-cao-byte commented 1 year ago

@otakuinny Thanks for your comment. Here is an example, I believe it can help indicate how the mechanism works.

Let's assume the parameters are as below:

and decrease_factor is 1/4 the range of the increase.

And there exist two kinds of contract calls.

Maintenance N+1

If Contract_A consumes more than threshold energy in the maintenance period N, then in the next maintenance period N+1, the amplification factor of each contract are:

Direct trigger to each function will cost:

Maintenance N+2

If Contract_A continues to consume more than threshold energy in the maintenance period N+1, then in the N+2 maintenance period:

Maintenance N+3

If Contract_A consumes less than threshold in the N+2 maintenance period, but Contract_B consumes more thanthreshold`, then in the N+3 period:

otakuinny commented 1 year ago

@otakuinny Thanks for your comment. Here is an example, I believe it can help indicate how the mechanism works.

Let's assume the parameters are as below:

  • threshold: 5_000_000_000
  • increase_factor: 1.5
  • max_factor: 2
  • trigger_base_energy: 2_000

and decrease_factor is 1/4 the range of the increase.

  • decrease_factor: 1 - (increase_factor - 1) / 4 = 1 - (1.5 - 1) / 4 = 0.875

And there exist two kinds of contract calls.

  • Contract_A.a_call(), its instructions cost energy 10_000, origin_A
  • Contract_B.b_call(), calls Contract_A.a_call() within the function, total cost energy 30_000, including origin_A 10_000 and origin_B 20_000.

Maintenance N+1

If Contract_A consumes more than threshold energy in the maintenance period N, then in the next maintenance period N+1, the amplification factor of each contract are:

  • factor_A: prev_factor_A increase_factor = 1 1.5 = 1.5
  • factor_B: MAX(1, prev_factor_B decrease_factor) = MAX(1, 1 0.875) = 1

Direct trigger to each function will cost:

  • Contract_A: a_call(), will cost: origin_A factor_A + trigger_base_energy factor_A = 10_000 1.5 + 2_000 1.5 = 18_000
  • Contract_B: b_call(), will cost: origin_B factor_B + origin_A factor_A = 20_000 1 + 10_000 1.5 = 35_000

Maintenance N+2

If Contract_A continues to consume more than threshold energy in the maintenance period N+1, then in the N+2 maintenance period:

  • factor_A: MIN(max_factor, prev_factor_A increase_factor) = MIN(2, 1.5 1.5) = 2
  • factor_B: MAX(1, prev_factor_B decrease_factor) = MAX(1, 1 0.875) = 1
  • Contract_A: a_call(), will cost: origin_A factor_A + trigger_base_energy factor_A = 10_000 2 + 2_000 2 = 24_000
  • Contract_B: b_call(), will cost: origin_B factor_B + origin_A factor_A = 20_000 1 + 10_000 2 = 40_000

Maintenance N+3

If Contract_A consumes less than threshold in the N+2 maintenance period, but Contract_B consumes more thanthreshold`, then in the N+3 period:

  • factor_A: MAX(1, prev_factor_A decrease_factor) = MAX(1, 2 0.875) = 1.75
  • factor_B: MIN(max_factor, prev_factor_B increase_factor) = MIN(2, 1 1.5) = 1.5
  • Contract_A: a_call(), will cost: origin_A factor_A + trigger_base_energy factor_A = 10_000 1.75 + 2_000 1.75 = 21_000
  • Contract_B: b_call(), will cost: origin_B factor_B + origin_A factor_A + trigger_base_energy factor_B = 20_000 1.5 + 10_000 1.75 + 2_000 1.5 = 50_500

Thank you @daniel-cao-byte for taking the time to write-up the detailed example with numbers. The tron resource known as energy is a measure of how long it takes for cpu to execute instructions in VM. 1 energy point = 1 micro second. So, if a call takes 100 micro seconds to finish, the call consumes 100 energy points. This being the case, dynamically raising the energy consumed by a contract will not make much sense as the call will always take the same amount of time assuming the input parameters and the storage data does not change.

Besides, the scam contracts that make millions of transactions can always rent more energy at a cheaper price even if the energy consumption is raised by a factor. A better system could be to charge TRX fees (just like 1 TRX for memo) when a contract exceeds a threshold in a cycle. This way we don't have to worry about complex calculations and max factors etc..

E.g. We can make the TRX fees configurable using SR proposals. Let's say it is 5 TRX and the threshold is 5 billion energy. If a contract uses more than 5 billion energy in a given cycle, write calls to that contract will incur a fee of 5 TRX in the next cycle. This fees can only be paid in TRX. When the contract consumes less than the threshold energy, the fee is not charged in the next cycle. I think this is much more effective and may even help reduce TRX circulation.

So, to recap, charging trx fees instead of charging more energy might be the way to go as the contract can provide 100% of the energy by renting it cheaply.

But we should be careful about setting the threshold value and the TRX fees so as to not hurt legitimate contracts. Also, when the contract call costs a trx fees, there should be a way for the caller to know ahead of time so a message can be shown on the dapp saying it'll cost the caller trx.

Just my 2 cents.

daniel-cao-byte commented 1 year ago

I think it's a very good advice to charge TRX fee instead of energy, we will carefully discuss and evaluate the suggestion.

daniel-cao-byte commented 1 year ago

After our discussion, we think that adding a percentage of penalty energy is more reasonable than charging a fixed TRX fee for whatever the transaction is or how much energy it consumes. Also, charging for trigger to a specific contract can be easily bypassed by a 'bridge' contract.

dwjorgeb commented 1 year ago

so, I just came here from the release notes of v4.7.0, and after I read the proposal I have come with the same conclusion as @otakuinny

Also, you do know that the phishing scammers just call the USDT contract directly, right? In this case, the transaction cost of the USDT contract will rise which leads to more expensive usdt transfer costs for everybody. Unless, I misunderstood your proposal.

Basically what this does is to turn USDT transfers more expensive for everyone, right?

daniel-cao-byte commented 1 year ago

This might be one of the TIP's side effect, but not only USDT, any contracts consuming too much energy will consume extra penalty energy.

dwjorgeb commented 1 year ago

This might be one of the TIP's side effect, but not only USDT, any contracts consuming too much energy will consume extra penalty energy.

USDT is 90% of the energy consumed on TRON (link), this TIP will just help turning TRON into Ethereum, where USDT payments for small value items (< 10 USDT) are unbearable pay via the TRON network, which will just push people to stop using TRON.

So, basically, this TIP is kneecapping one of the biggest uses of the TRON network without providing any benefits whatsoever to anyone else, nor any meaningful spam prevention system.

How was this TIP approved?

otakuinny commented 1 year ago

This might be one of the TIP's side effect, but not only USDT, any contracts consuming too much energy will consume extra penalty energy.

USDT is 90% of the energy consumed on TRON (link), this TIP will just help turning TRON into Ethereum, where USDT payments for small value items (< 10 USDT) are unbearable pay via the TRON network, which will just push people to stop using TRON.

So, basically, this TIP is kneecapping one of the biggest uses of the TRON network without providing any benefits whatsoever to anyone else, nor any meaningful spam prevention system.

How was this TIP approved?

Their aim is to make USDT transactions more expensive, but they can't admit that. So, they offer some bs explanation about other "mythical" contracts consuming a lot of energy. They know that we know they know they are wrong. They just don't care. This is very common among all centralized cryptos.

ethan1844 commented 1 year ago

Close this issue as it is implemented by GreatVoyage-v4.7.0.1. Check TIP detail at TIP-491 Check implementation PR at https://github.com/tronprotocol/java-tron/pull/4873