Skip to content

Commit

Permalink
feat(freezeV2): optimize Stake2.0 code
Browse files Browse the repository at this point in the history
  • Loading branch information
lxcmyf committed Aug 23, 2023
1 parent e9bf1d8 commit 699c044
Show file tree
Hide file tree
Showing 17 changed files with 223 additions and 179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public boolean execute(Object result) throws ContractExeException {
List<UnFreezeV2> unfrozenV2List = ownerCapsule.getUnfrozenV2List();
long now = dynamicStore.getLatestBlockHeaderTimestamp();
AtomicLong atomicWithdrawExpireBalance = new AtomicLong(0L);
/* The triple object is defined by resource type, with left representing the pair object
corresponding to bandwidth, middle representing the pair object corresponding to energy, and
right representing the pair object corresponding to tron power. The pair object for each
resource type, left represents resource weight, and right represents the number of unfreeze
resources for that resource type. */
Triple<Pair<AtomicLong, AtomicLong>, Pair<AtomicLong, AtomicLong>, Pair<AtomicLong, AtomicLong>>
triple = Triple.of(
Pair.of(new AtomicLong(0L), new AtomicLong(0L)),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.tron.core.actuator;

import static org.tron.core.actuator.ActuatorConstant.NOT_EXIST_STR;
import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL;
import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_PERIOD;
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;
import static org.tron.protos.contract.Common.ResourceCode;
Expand Down Expand Up @@ -66,7 +67,8 @@ public boolean execute(Object result) throws ContractExeException {
DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore();
long delegateBalance = delegateResourceContract.getBalance();
boolean lock = delegateResourceContract.getLock();
long lockPeriod = getLockPeriod(dynamicStore, delegateResourceContract);
long lockPeriod = getLockPeriod(dynamicStore.supportMaxDelegateLockPeriod(),
delegateResourceContract);
byte[] receiverAddress = delegateResourceContract.getReceiverAddress().toByteArray();

// delegate resource to receiver
Expand Down Expand Up @@ -155,14 +157,12 @@ public boolean validate() throws ContractValidateException {

long accountNetUsage = ownerCapsule.getNetUsage();
if (null != this.getTx() && this.getTx().isTransactionCreate()) {
accountNetUsage += TransactionUtil.estimateConsumeBandWidthSize(
ownerCapsule.getBalance());
accountNetUsage += TransactionUtil.estimateConsumeBandWidthSize(dynamicStore,
ownerCapsule.getBalance());
}
long netUsage = (long) (accountNetUsage * TRX_PRECISION * ((double)
(dynamicStore.getTotalNetWeight()) / dynamicStore.getTotalNetLimit()));

long v2NetUsage = getV2NetUsage(ownerCapsule, netUsage);

if (ownerCapsule.getFrozenV2BalanceForBandwidth() - v2NetUsage < delegateBalance) {
throw new ContractValidateException(
"delegateBalance must be less than or equal to available FreezeBandwidthV2 balance");
Expand All @@ -175,9 +175,7 @@ public boolean validate() throws ContractValidateException {

long energyUsage = (long) (ownerCapsule.getEnergyUsage() * TRX_PRECISION * ((double)
(dynamicStore.getTotalEnergyWeight()) / dynamicStore.getTotalEnergyCurrentLimit()));

long v2EnergyUsage = getV2EnergyUsage(ownerCapsule, energyUsage);

if (ownerCapsule.getFrozenV2BalanceForEnergy() - v2EnergyUsage < delegateBalance) {
throw new ContractValidateException(
"delegateBalance must be less than or equal to available FreezeEnergyV2 balance");
Expand Down Expand Up @@ -211,7 +209,7 @@ public boolean validate() throws ContractValidateException {

boolean lock = delegateResourceContract.getLock();
if (lock && dynamicStore.supportMaxDelegateLockPeriod()) {
long lockPeriod = getLockPeriod(dynamicStore, delegateResourceContract);
long lockPeriod = getLockPeriod(true, delegateResourceContract);
long maxDelegateLockPeriod = dynamicStore.getMaxDelegateLockPeriod();
if (lockPeriod < 0 || lockPeriod > maxDelegateLockPeriod) {
throw new ContractValidateException(
Expand Down Expand Up @@ -249,20 +247,20 @@ public boolean validate() throws ContractValidateException {
return true;
}

private long getLockPeriod(DynamicPropertiesStore dynamicStore,
private long getLockPeriod(boolean supportMaxDelegateLockPeriod,
DelegateResourceContract delegateResourceContract) {
long lockPeriod = delegateResourceContract.getLockPeriod();
if (dynamicStore.supportMaxDelegateLockPeriod()) {
return lockPeriod == 0 ? DELEGATE_PERIOD / 3000 : lockPeriod;
if (supportMaxDelegateLockPeriod) {
return lockPeriod == 0 ? DELEGATE_PERIOD / BLOCK_PRODUCED_INTERVAL : lockPeriod;
} else {
return 0;
return DELEGATE_PERIOD / BLOCK_PRODUCED_INTERVAL;
}
}

private void validRemainTime(ResourceCode resourceCode, long lockPeriod, long expireTime,
long now) throws ContractValidateException {
long remainTime = expireTime - now;
if (lockPeriod * 3 * 1000 < remainTime) {
if (lockPeriod * BLOCK_PRODUCED_INTERVAL < remainTime) {
throw new ContractValidateException(
"The lock period for " + resourceCode.name() + " this time cannot be less than the "
+ "remaining time[" + remainTime + "ms] of the last lock period for "
Expand Down Expand Up @@ -295,11 +293,7 @@ private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boole
//modify DelegatedResourceStore
long expireTime = 0;
if (lock) {
if (dynamicPropertiesStore.supportMaxDelegateLockPeriod()) {
expireTime = now + lockPeriod * 3 * 1000;
} else {
expireTime = now + DELEGATE_PERIOD;
}
expireTime = now + lockPeriod * BLOCK_PRODUCED_INTERVAL;
}
byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, lock);
DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore.get(key);
Expand Down
6 changes: 4 additions & 2 deletions actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.tron.core.Constant.DYNAMIC_ENERGY_INCREASE_FACTOR_RANGE;
import static org.tron.core.Constant.DYNAMIC_ENERGY_MAX_FACTOR_RANGE;
import static org.tron.core.config.Parameter.ChainConstant.ONE_YEAR_BLOCK_NUMBERS;

import org.tron.common.utils.ForkController;
import org.tron.core.config.Parameter.ForkBlockVersionConsts;
Expand Down Expand Up @@ -714,10 +715,11 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
"Bad chain parameter id [MAX_DELEGATE_LOCK_PERIOD]");
}
long maxDelegateLockPeriod = dynamicPropertiesStore.getMaxDelegateLockPeriod();
if (value <= maxDelegateLockPeriod || value > 10512000L) {
if (value <= maxDelegateLockPeriod || value > ONE_YEAR_BLOCK_NUMBERS) {
throw new ContractValidateException(
"This value[MAX_DELEGATE_LOCK_PERIOD] is only allowed to be greater than "
+ maxDelegateLockPeriod + " and less than or equal to 10512000 !");
+ maxDelegateLockPeriod + " and less than or equal to " + ONE_YEAR_BLOCK_NUMBERS
+ " !");
}
if (dynamicPropertiesStore.getUnfreezeDelayDays() == 0) {
throw new ContractValidateException(
Expand Down
72 changes: 13 additions & 59 deletions actuator/src/main/java/org/tron/core/utils/TransactionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.tron.core.capsule.TransactionCapsule;
import org.tron.core.exception.PermissionException;
import org.tron.core.exception.SignatureFormatException;
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.protos.Protocol.Permission;
import org.tron.protos.Protocol.Permission.PermissionType;
import org.tron.protos.Protocol.Transaction;
Expand Down Expand Up @@ -222,7 +223,7 @@ public TransactionSignWeight getTransactionSignWeight(Transaction trx) {
}
tswBuilder.setPermission(permission);
if (trx.getSignatureCount() > 0) {
List<ByteString> approveList = new ArrayList<ByteString>();
List<ByteString> approveList = new ArrayList<>();
long currentWeight = TransactionCapsule.checkWeight(permission, trx.getSignatureList(),
Sha256Hash.hash(CommonParameter.getInstance()
.isECKeyCryptoEngine(), trx.getRawData().toByteArray()), approveList);
Expand Down Expand Up @@ -253,71 +254,24 @@ public TransactionSignWeight getTransactionSignWeight(Transaction trx) {
return tswBuilder.build();
}

public static long estimateConsumeBandWidthSize(long balance) {
DelegateResourceContract.Builder builder = DelegateResourceContract.newBuilder()
.setLock(true)
.setBalance(balance);
long builderSize = builder.build().getSerializedSize();

DelegateResourceContract.Builder builder2 = DelegateResourceContract.newBuilder()
.setBalance(TRX_PRECISION);
long builder2Size = builder2.build().getSerializedSize();
long addSize = Math.max(builderSize - builder2Size, 0L);

return DELEGATE_COST_BASE_SIZE + addSize;
}

// only for testing
public static long consumeBandWidthSize(
final TransactionCapsule transactionCapsule,
ChainBaseManager chainBaseManager) {
long bytesSize;

boolean supportVM = chainBaseManager.getDynamicPropertiesStore().supportVM();
if (supportVM) {
bytesSize = transactionCapsule.getInstance().toBuilder().clearRet().build().getSerializedSize();
} else {
bytesSize = transactionCapsule.getSerializedSize();
}

List<Transaction.Contract> contracts = transactionCapsule.getInstance().getRawData().getContractList();
for (Transaction.Contract contract : contracts) {
if (contract.getType() == Contract.ContractType.ShieldedTransferContract) {
continue;
}
if (supportVM) {
bytesSize += Constant.MAX_RESULT_SIZE_IN_TX;
}
}

return bytesSize;
}

public static long estimateConsumeBandWidthSize(final AccountCapsule ownerCapsule,
ChainBaseManager chainBaseManager) {
public static long estimateConsumeBandWidthSize(DynamicPropertiesStore dps, long balance) {
DelegateResourceContract.Builder builder;
if (chainBaseManager.getDynamicPropertiesStore().supportMaxDelegateLockPeriod()) {
if (dps.supportMaxDelegateLockPeriod()) {
builder = DelegateResourceContract.newBuilder()
.setLock(true)
.setLockPeriod(chainBaseManager.getDynamicPropertiesStore().getMaxDelegateLockPeriod())
.setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth());
.setLock(true)
.setLockPeriod(dps.getMaxDelegateLockPeriod())
.setBalance(balance);
} else {
builder = DelegateResourceContract.newBuilder()
.setLock(true)
.setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth());
.setLock(true)
.setBalance(balance);
}
TransactionCapsule fakeTransactionCapsule = new TransactionCapsule(builder.build()
, ContractType.DelegateResourceContract);
long size1 = consumeBandWidthSize(fakeTransactionCapsule, chainBaseManager);

long builderSize = builder.build().getSerializedSize();
DelegateResourceContract.Builder builder2 = DelegateResourceContract.newBuilder()
.setBalance(TRX_PRECISION);
TransactionCapsule fakeTransactionCapsule2 = new TransactionCapsule(builder2.build()
, ContractType.DelegateResourceContract);
long size2 = consumeBandWidthSize(fakeTransactionCapsule2, chainBaseManager);
long addSize = Math.max(size1 - size2, 0L);
.setBalance(TRX_PRECISION);
long builder2Size = builder2.build().getSerializedSize();
long addSize = Math.max(builderSize - builder2Size, 0L);

return DELEGATE_COST_BASE_SIZE + addSize;
}

}
26 changes: 15 additions & 11 deletions actuator/src/main/java/org/tron/core/vm/program/Program.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import static org.apache.commons.lang3.ArrayUtils.nullToEmpty;
import static org.tron.common.utils.ByteUtil.stripLeadingZeroes;
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;
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;
import static org.tron.protos.contract.Common.ResourceCode.UNRECOGNIZED;

import com.google.protobuf.ByteString;
import java.math.BigInteger;
Expand Down Expand Up @@ -557,7 +561,7 @@ private long transferFrozenV2BalanceToInheritor(byte[] ownerAddr, byte[] inherit
ownerCapsule.setLatestConsumeTime(now);
if (ownerCapsule.getNetUsage() > 0) {
bandwidthProcessor.unDelegateIncrease(inheritorCapsule, ownerCapsule,
ownerCapsule.getNetUsage(), Common.ResourceCode.BANDWIDTH, now);
ownerCapsule.getNetUsage(), BANDWIDTH, now);
}

EnergyProcessor energyProcessor =
Expand All @@ -567,7 +571,7 @@ private long transferFrozenV2BalanceToInheritor(byte[] ownerAddr, byte[] inherit
ownerCapsule.setLatestConsumeTimeForEnergy(now);
if (ownerCapsule.getEnergyUsage() > 0) {
energyProcessor.unDelegateIncrease(inheritorCapsule, ownerCapsule,
ownerCapsule.getEnergyUsage(), Common.ResourceCode.ENERGY, now);
ownerCapsule.getEnergyUsage(), ENERGY, now);
}

// withdraw expire unfrozen balance
Expand All @@ -594,9 +598,9 @@ private long transferFrozenV2BalanceToInheritor(byte[] ownerAddr, byte[] inherit
private void clearOwnerFreezeV2(AccountCapsule ownerCapsule) {
ownerCapsule.clearFrozenV2();
ownerCapsule.setNetUsage(0);
ownerCapsule.setNewWindowSize(Common.ResourceCode.BANDWIDTH, 0);
ownerCapsule.setNewWindowSize(BANDWIDTH, 0);
ownerCapsule.setEnergyUsage(0);
ownerCapsule.setNewWindowSize(Common.ResourceCode.ENERGY, 0);
ownerCapsule.setNewWindowSize(ENERGY, 0);
ownerCapsule.clearUnfrozenV2();
}

Expand Down Expand Up @@ -2077,11 +2081,11 @@ public boolean unDelegateResource(
private Common.ResourceCode parseResourceCode(DataWord resourceType) {
switch (resourceType.intValue()) {
case 0:
return Common.ResourceCode.BANDWIDTH;
return BANDWIDTH;
case 1:
return Common.ResourceCode.ENERGY;
return ENERGY;
default:
return Common.ResourceCode.UNRECOGNIZED;
return UNRECOGNIZED;
}
}

Expand All @@ -2090,13 +2094,13 @@ private Common.ResourceCode parseResourceCodeV2(DataWord resourceType) {
byte type = resourceType.sValue().byteValueExact();
switch (type) {
case 0:
return Common.ResourceCode.BANDWIDTH;
return BANDWIDTH;
case 1:
return Common.ResourceCode.ENERGY;
return ENERGY;
case 2:
return Common.ResourceCode.TRON_POWER;
return TRON_POWER;
default:
return Common.ResourceCode.UNRECOGNIZED;
return UNRECOGNIZED;
}
} catch (ArithmeticException e) {
logger.warn("TVM ParseResourceCodeV2: invalid resource code: {}", resourceType.sValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.tron.core.vm.repository.Repository;
import org.tron.protos.Protocol;


public class FreezeV2Util {

private FreezeV2Util() {
Expand Down
18 changes: 12 additions & 6 deletions chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.tron.core.db;

import static java.lang.Math.ceil;
import static java.lang.Math.round;
import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL;
import static org.tron.core.config.Parameter.ChainConstant.WINDOW_SIZE_PRECISION;

Expand Down Expand Up @@ -134,7 +132,11 @@ public long increaseV2(AccountCapsule accountCapsule, ResourceCode resourceCode,
}

public void unDelegateIncrease(AccountCapsule owner, final AccountCapsule receiver,
long transferUsage, ResourceCode resourceCode, long now) {
long transferUsage, ResourceCode resourceCode, long now) {
if (dynamicPropertiesStore.supportAllowCancelAllUnfreezeV2()) {
unDelegateIncreaseV2(owner, receiver, transferUsage, resourceCode, now);
return;
}
long lastOwnerTime = owner.getLastConsumeTime(resourceCode);
long ownerUsage = owner.getUsage(resourceCode);
// Update itself first
Expand All @@ -151,6 +153,7 @@ public void unDelegateIncrease(AccountCapsule owner, final AccountCapsule receiv
owner.setNewWindowSize(resourceCode, this.windowSize);
owner.setUsage(resourceCode, 0);
owner.setLatestTime(resourceCode, now);
return;
}
// calculate new windowSize
long newOwnerWindowSize = getNewWindowSize(ownerUsage, remainOwnerWindowSize, transferUsage,
Expand All @@ -160,7 +163,7 @@ public void unDelegateIncrease(AccountCapsule owner, final AccountCapsule receiv
owner.setLatestTime(resourceCode, now);
}

public long unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule receiver,
public void unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule receiver,
long transferUsage, ResourceCode resourceCode, long now) {
long lastOwnerTime = owner.getLastConsumeTime(resourceCode);
long ownerUsage = owner.getUsage(resourceCode);
Expand All @@ -170,7 +173,9 @@ public long unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule rece
// mean ownerUsage == 0 and transferUsage == 0
if (newOwnerUsage == 0) {
owner.setNewWindowSizeV2(resourceCode, this.windowSize * WINDOW_SIZE_PRECISION);
return newOwnerUsage;
owner.setUsage(resourceCode, 0);
owner.setLatestTime(resourceCode, now);
return;
}

long remainOwnerWindowSizeV2 = owner.getWindowSizeV2(resourceCode);
Expand All @@ -185,7 +190,8 @@ public long unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule rece
newOwnerUsage);
newOwnerWindowSize = Math.min(newOwnerWindowSize, this.windowSize * WINDOW_SIZE_PRECISION);
owner.setNewWindowSizeV2(resourceCode, newOwnerWindowSize);
return newOwnerUsage;
owner.setUsage(resourceCode, newOwnerUsage);
owner.setLatestTime(resourceCode, now);
}

private long getNewWindowSize(long lastUsage, long lastWindowSize, long usage,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.tron.core.store;

import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL;
import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_PERIOD;

import com.google.protobuf.ByteString;
Expand Down Expand Up @@ -2824,11 +2825,12 @@ public long getMaxDelegateLockPeriod() {
return Optional.ofNullable(getUnchecked(MAX_DELEGATE_LOCK_PERIOD))
.map(BytesCapsule::getData)
.map(ByteArray::toLong)
.orElse(DELEGATE_PERIOD / 3000);
.orElse(DELEGATE_PERIOD / BLOCK_PRODUCED_INTERVAL);
}

public boolean supportMaxDelegateLockPeriod() {
return (getMaxDelegateLockPeriod() > DELEGATE_PERIOD / 3000) && getUnfreezeDelayDays() > 0;
return (getMaxDelegateLockPeriod() > DELEGATE_PERIOD / BLOCK_PRODUCED_INTERVAL) &&
getUnfreezeDelayDays() > 0;
}

private static class DynamicResourceProperties {
Expand Down
Loading

0 comments on commit 699c044

Please sign in to comment.