Skip to content

Commit

Permalink
feat(freezeV2): optimize usage merging
Browse files Browse the repository at this point in the history
Signed-off-by: liuxincheng <[email protected]>
  • Loading branch information
lxcmyf committed Oct 14, 2022
1 parent 9a4be62 commit 2ef8e7d
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 11 deletions.
21 changes: 21 additions & 0 deletions chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import java.util.Map;
import java.util.Objects;

import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL;
import static org.tron.core.config.Parameter.ChainConstant.WINDOW_SIZE_MS;
import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH;
import static org.tron.protos.contract.Common.ResourceCode.ENERGY;
import static org.tron.protos.contract.Common.ResourceCode.TRON_POWER;
Expand Down Expand Up @@ -1262,4 +1264,23 @@ public void clearUnfrozenV2() {
this.account = this.account.toBuilder().clearUnfrozenV2().build();
}

public long getNetWindowSize() {
long netWindowSize = this.account.getNetWindowSize();
return netWindowSize == 0 ? WINDOW_SIZE_MS / BLOCK_PRODUCED_INTERVAL : netWindowSize;
}

public void setNetWindowSize(long netWindowSize) {
this.account = this.account.toBuilder().setNetWindowSize(netWindowSize).build();
}

public long getEnergyWindowSize() {
long energyWindowSize = this.account.getAccountResource().getEnergyWindowSize();
return energyWindowSize == 0 ? WINDOW_SIZE_MS / BLOCK_PRODUCED_INTERVAL : energyWindowSize;
}

public void setEnergyWindowSize(long energyWindowSize) {
this.account = this.account.toBuilder().setAccountResource(this.account.getAccountResource()
.toBuilder().setEnergyWindowSize(energyWindowSize).build()).build();
}

}
20 changes: 13 additions & 7 deletions chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.tron.protos.contract.AssetIssueContractOuterClass.TransferAssetContract;
import org.tron.protos.contract.BalanceContract.TransferContract;

import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH;

@Slf4j(topic = "DB")
public class BandwidthProcessor extends ResourceProcessor {

Expand All @@ -42,7 +44,8 @@ public void updateUsage(AccountCapsule accountCapsule) {
private void updateUsage(AccountCapsule accountCapsule, long now) {
long oldNetUsage = accountCapsule.getNetUsage();
long latestConsumeTime = accountCapsule.getLatestConsumeTime();
accountCapsule.setNetUsage(increase(oldNetUsage, 0, latestConsumeTime, now));
accountCapsule.setNetUsage(increase(accountCapsule, BANDWIDTH,
oldNetUsage, 0, latestConsumeTime, now));
long oldFreeNetUsage = accountCapsule.getFreeNetUsage();
long latestConsumeFreeTime = accountCapsule.getLatestConsumeFreeTime();
accountCapsule.setFreeNetUsage(increase(oldFreeNetUsage, 0, latestConsumeFreeTime, now));
Expand Down Expand Up @@ -183,13 +186,14 @@ public boolean consumeBandwidthForCreateNewAccount(AccountCapsule accountCapsule
long netUsage = accountCapsule.getNetUsage();
long latestConsumeTime = accountCapsule.getLatestConsumeTime();
long netLimit = calculateGlobalNetLimit(accountCapsule);
long newNetUsage = increase(netUsage, 0, latestConsumeTime, now);
long newNetUsage = increase(accountCapsule, BANDWIDTH, netUsage, 0, latestConsumeTime, now);

long netCost = bytes * createNewAccountBandwidthRatio;
if (netCost <= (netLimit - newNetUsage)) {
latestConsumeTime = now;
long latestOperationTime = chainBaseManager.getHeadBlockTimeStamp();
newNetUsage = increase(newNetUsage, netCost, latestConsumeTime, now);
newNetUsage = increase(accountCapsule, BANDWIDTH,
newNetUsage, netCost, latestConsumeTime, now);
accountCapsule.setLatestConsumeTime(latestConsumeTime);
accountCapsule.setLatestOperationTime(latestOperationTime);
accountCapsule.setNetUsage(newNetUsage);
Expand Down Expand Up @@ -313,7 +317,8 @@ private boolean useAssetAccountNet(Contract contract, AccountCapsule accountCaps
long latestConsumeTime = issuerAccountCapsule.getLatestConsumeTime();
long issuerNetLimit = calculateGlobalNetLimit(issuerAccountCapsule);

long newIssuerNetUsage = increase(issuerNetUsage, 0, latestConsumeTime, now);
long newIssuerNetUsage = increase(accountCapsule, BANDWIDTH,
issuerNetUsage, 0, latestConsumeTime, now);

if (bytes > (issuerNetLimit - newIssuerNetUsage)) {
logger.debug("The " + tokenID + " issuer's bandwidth is not enough");
Expand All @@ -325,7 +330,8 @@ private boolean useAssetAccountNet(Contract contract, AccountCapsule accountCaps
publicLatestFreeNetTime = now;
long latestOperationTime = chainBaseManager.getHeadBlockTimeStamp();

newIssuerNetUsage = increase(newIssuerNetUsage, bytes, latestConsumeTime, now);
newIssuerNetUsage = increase(accountCapsule, BANDWIDTH,
newIssuerNetUsage, bytes, latestConsumeTime, now);
newFreeAssetNetUsage = increase(newFreeAssetNetUsage,
bytes, latestAssetOperationTime, now);
newPublicFreeAssetNetUsage = increase(newPublicFreeAssetNetUsage, bytes,
Expand Down Expand Up @@ -390,7 +396,7 @@ private boolean useAccountNet(AccountCapsule accountCapsule, long bytes, long no
long latestConsumeTime = accountCapsule.getLatestConsumeTime();
long netLimit = calculateGlobalNetLimit(accountCapsule);

long newNetUsage = increase(netUsage, 0, latestConsumeTime, now);
long newNetUsage = increase(accountCapsule, BANDWIDTH, netUsage, 0, latestConsumeTime, now);

if (bytes > (netLimit - newNetUsage)) {
logger.debug("net usage is running out, now use free net usage");
Expand All @@ -399,7 +405,7 @@ private boolean useAccountNet(AccountCapsule accountCapsule, long bytes, long no

latestConsumeTime = now;
long latestOperationTime = chainBaseManager.getHeadBlockTimeStamp();
newNetUsage = increase(newNetUsage, bytes, latestConsumeTime, now);
newNetUsage = increase(accountCapsule, BANDWIDTH, newNetUsage, bytes, latestConsumeTime, now);
accountCapsule.setNetUsage(newNetUsage);
accountCapsule.setLatestOperationTime(latestOperationTime);
accountCapsule.setLatestConsumeTime(latestConsumeTime);
Expand Down
12 changes: 8 additions & 4 deletions chainbase/src/main/java/org/tron/core/db/EnergyProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.protos.Protocol.Account.AccountResource;

import static org.tron.protos.contract.Common.ResourceCode.ENERGY;

@Slf4j(topic = "DB")
public class EnergyProcessor extends ResourceProcessor {

Expand All @@ -41,7 +43,8 @@ private void updateUsage(AccountCapsule accountCapsule, long now) {
long oldEnergyUsage = accountResource.getEnergyUsage();
long latestConsumeTime = accountResource.getLatestConsumeTimeForEnergy();

accountCapsule.setEnergyUsage(increase(oldEnergyUsage, 0, latestConsumeTime, now));
accountCapsule.setEnergyUsage(increase(accountCapsule, ENERGY,
oldEnergyUsage, 0, latestConsumeTime, now));
}

public void updateTotalEnergyAverageUsage() {
Expand Down Expand Up @@ -101,7 +104,7 @@ public boolean useEnergy(AccountCapsule accountCapsule, long energy, long now) {
long latestConsumeTime = accountCapsule.getAccountResource().getLatestConsumeTimeForEnergy();
long energyLimit = calculateGlobalEnergyLimit(accountCapsule);

long newEnergyUsage = increase(energyUsage, 0, latestConsumeTime, now);
long newEnergyUsage = increase(accountCapsule, ENERGY, energyUsage, 0, latestConsumeTime, now);

if (energy > (energyLimit - newEnergyUsage)
&& dynamicPropertiesStore.getAllowTvmFreeze() == 0) {
Expand All @@ -110,7 +113,8 @@ public boolean useEnergy(AccountCapsule accountCapsule, long energy, long now) {

latestConsumeTime = now;
long latestOperationTime = dynamicPropertiesStore.getLatestBlockHeaderTimestamp();
newEnergyUsage = increase(newEnergyUsage, energy, latestConsumeTime, now);
newEnergyUsage = increase(accountCapsule, ENERGY,
newEnergyUsage, energy, latestConsumeTime, now);
accountCapsule.setEnergyUsage(newEnergyUsage);
accountCapsule.setLatestOperationTime(latestOperationTime);
accountCapsule.setLatestConsumeTimeForEnergy(latestConsumeTime);
Expand Down Expand Up @@ -146,7 +150,7 @@ public long getAccountLeftEnergyFromFreeze(AccountCapsule accountCapsule) {
long latestConsumeTime = accountCapsule.getAccountResource().getLatestConsumeTimeForEnergy();
long energyLimit = calculateGlobalEnergyLimit(accountCapsule);

long newEnergyUsage = increase(energyUsage, 0, latestConsumeTime, now);
long newEnergyUsage = increase(accountCapsule, ENERGY, energyUsage, 0, latestConsumeTime, now);

return max(energyLimit - newEnergyUsage, 0); // us
}
Expand Down
39 changes: 39 additions & 0 deletions chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.tron.core.db;

import static org.tron.common.parameter.CommonParameter.PARAMETER;
import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL;

import org.tron.common.utils.Commons;
Expand All @@ -13,6 +14,7 @@
import org.tron.core.exception.TooBigTransactionResultException;
import org.tron.core.store.AccountStore;
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.protos.contract.Common.ResourceCode;

abstract class ResourceProcessor {

Expand Down Expand Up @@ -59,6 +61,43 @@ protected long increase(long lastUsage, long usage, long lastTime, long now, lon
return getUsage(averageLastUsage, windowSize);
}

protected long increase(AccountCapsule accountCapsule, ResourceCode resourceCode,
long lastUsage, long usage, long lastTime, long now) {
long lastWindowSize = resourceCode == ResourceCode.BANDWIDTH ?
accountCapsule.getNetWindowSize() : accountCapsule.getEnergyWindowSize();
long averageLastUsage = divideCeil(lastUsage * precision, lastWindowSize);
long averageUsage = divideCeil(usage * precision, lastWindowSize);

if (lastTime != now) {
assert now > lastTime;
if (lastTime + lastWindowSize > now) {
long delta = now - lastTime;
double decay = (lastWindowSize - delta) / (double) lastWindowSize;
averageLastUsage = Math.round(averageLastUsage * decay);
} else {
averageLastUsage = 0;
}
}
averageLastUsage += averageUsage;

long newUsage = getUsage(averageLastUsage, lastWindowSize);
if (PARAMETER.unfreezeDelayDays > 0) {
long remainUsage = getUsage(averageUsage, lastWindowSize);
if (newUsage == 0) {
return 0;
}
long newWindowSize = ((lastWindowSize - (now - lastTime)) * remainUsage
+ lastWindowSize * usage) / newUsage;
if (resourceCode == ResourceCode.BANDWIDTH) {
accountCapsule.setNetWindowSize(newWindowSize);
} else {
accountCapsule.setEnergyWindowSize(newWindowSize);
}
}

return newUsage;
}

private long divideCeil(long numerator, long denominator) {
return (numerator / denominator) + ((numerator % denominator) > 0 ? 1 : 0);
}
Expand Down
3 changes: 3 additions & 0 deletions protocol/src/main/protos/core/Tron.proto
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ message Account {
// the identity of this account, case insensitive
bytes account_id = 23;

int64 net_window_size = 24;

message AccountResource {
// energy resource, get from frozen
int64 energy_usage = 1;
Expand All @@ -209,6 +211,7 @@ message Account {
int64 storage_usage = 7;
int64 latest_exchange_storage_time = 8;

int64 energy_window_size = 9;
}
AccountResource account_resource = 26;
bytes codeHash = 30;
Expand Down

0 comments on commit 2ef8e7d

Please sign in to comment.