tip: 491
title: Dynamic Energy Model
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
This tip proposes a mechanism to perform dynamic regulation of energy in contracts to balance the distribution of energy among contracts.
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.
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,
- It will not only lead to more users being defrauded to suffer asset loss;
- It will also make it difficult for the dApp ecosystem to grow. The capacity of the network is limited, and when the network is filled with a large number of queued spam transactions, other transactions will have to wait longer, which will be a very bad experience for both the users and the dApp developers.
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.
Three main parameters controlled by the proposal are introduced in the scheme, and the meaning of each parameter is as follows,
threshold
: threshold value of base energy consumption for the contract hit rule, then the energy consumption factor will be adjusted.increase_factor
: the rate of the consumption factor increase when the base energy consumption of the contract exceeds the thresholdmax_factor
: the maximum value of the energy consumption factor
And there is a derivative parameter for calculation:
decrease_factor
: a quarter ofincrease_factor
, the rate of the consumption factor decrease when the base energy consumption of the contract does not exceed the threshold
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)
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.
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.
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.
There are several API changes involved in this TIP.
- 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.
update_cycle
: the current maintenance period number.
- Add
energy_penalty
in contract trigger results, involving/wallet/triggerconstantcontract
andtriggersmartcontract
{
"...": "...",
"energy_used": 643,
"energy_penalty": 200
}
energy_penalty
: the total penalty energy in the transaction, included in energy_used
.
- Add
energy_penalty_total
in transaction receipts, involving/wallet/gettransactioninfobyid
and/wallet/gettransactionreceiptbyid
/wallet/gettransactioninfobyid
{
"id": "954bd5d919677908cb87c685d7931afe1943c4fe93ec4625079060e7ee8ee08f",
"blockNumber": 47177000,
"...": "...",
"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, included in receipt.energy_usage_total
.
/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, included in Receipt.energy_usage_total
.
There are no backward compatibility issues.
There are no security considerations.