Skip to content

Commit

Permalink
feat(freezeV2): optimize Stake2.0 code (tronprotocol#5426)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: halibobo1205 <[email protected]>
Co-authored-by: chaozhu <[email protected]>
  • Loading branch information
3 people authored Aug 23, 2023
1 parent a4100b6 commit a02fbb0
Show file tree
Hide file tree
Showing 28 changed files with 633 additions and 498 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,11 +1,14 @@
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;
import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH;
import static org.tron.protos.contract.Common.ResourceCode.ENERGY;
import static org.tron.core.vm.utils.FreezeV2Util.getV2EnergyUsage;
import static org.tron.core.vm.utils.FreezeV2Util.getV2NetUsage;

import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
Expand Down Expand Up @@ -64,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 @@ -143,7 +147,7 @@ public boolean validate() throws ContractValidateException {

long delegateBalance = delegateResourceContract.getBalance();
if (delegateBalance < TRX_PRECISION) {
throw new ContractValidateException("delegateBalance must be more than 1TRX");
throw new ContractValidateException("delegateBalance must be greater than or equal to 1 TRX");
}

switch (delegateResourceContract.getResource()) {
Expand All @@ -153,22 +157,15 @@ public boolean validate() throws ContractValidateException {

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

long remainNetUsage = netUsage
- ownerCapsule.getFrozenBalance()
- ownerCapsule.getAcquiredDelegatedFrozenBalanceForBandwidth()
- ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth();

remainNetUsage = Math.max(0, remainNetUsage);

if (ownerCapsule.getFrozenV2BalanceForBandwidth() - remainNetUsage < delegateBalance) {
long v2NetUsage = getV2NetUsage(ownerCapsule, netUsage);
if (ownerCapsule.getFrozenV2BalanceForBandwidth() - v2NetUsage < delegateBalance) {
throw new ContractValidateException(
"delegateBalance must be less than available FreezeBandwidthV2 balance");
"delegateBalance must be less than or equal to available FreezeBandwidthV2 balance");
}
}
break;
Expand All @@ -178,17 +175,10 @@ public boolean validate() throws ContractValidateException {

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

long remainEnergyUsage = energyUsage
- ownerCapsule.getEnergyFrozenBalance()
- ownerCapsule.getAcquiredDelegatedFrozenBalanceForEnergy()
- ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy();

remainEnergyUsage = Math.max(0, remainEnergyUsage);

if (ownerCapsule.getFrozenV2BalanceForEnergy() - remainEnergyUsage < delegateBalance) {
long v2EnergyUsage = getV2EnergyUsage(ownerCapsule, energyUsage);
if (ownerCapsule.getFrozenV2BalanceForEnergy() - v2EnergyUsage < delegateBalance) {
throw new ContractValidateException(
"delegateBalance must be less than available FreezeEnergyV2 balance");
"delegateBalance must be less than or equal to available FreezeEnergyV2 balance");
}
}
break;
Expand Down Expand Up @@ -219,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 @@ -257,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 @@ -303,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
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,15 @@ public boolean validate() throws ContractValidateException {
throw new ContractValidateException("frozenBalance must be positive");
}
if (frozenBalance < TRX_PRECISION) {
throw new ContractValidateException("frozenBalance must be more than 1TRX");
throw new ContractValidateException("frozenBalance must be greater than or equal to 1 TRX");
}

int frozenCount = accountCapsule.getFrozenCount();
if (!(frozenCount == 0 || frozenCount == 1)) {
throw new ContractValidateException("frozenCount must be 0 or 1");
}
if (frozenBalance > accountCapsule.getBalance()) {
throw new ContractValidateException("frozenBalance must be less than accountBalance");
throw new ContractValidateException("frozenBalance must be less than or equal to accountBalance");
}

long frozenDuration = freezeBalanceContract.getFrozenDuration();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public boolean execute(Object result) throws ContractExeException {
accountCapsule.initializeOldTronPower();
}

long newBalance = accountCapsule.getBalance() - freezeBalanceV2Contract.getFrozenBalance();
long frozenBalance = freezeBalanceV2Contract.getFrozenBalance();
long newBalance = accountCapsule.getBalance() - frozenBalance;

switch (freezeBalanceV2Contract.getResource()) {
case BANDWIDTH:
Expand Down Expand Up @@ -133,11 +133,11 @@ public boolean validate() throws ContractValidateException {
throw new ContractValidateException("frozenBalance must be positive");
}
if (frozenBalance < TRX_PRECISION) {
throw new ContractValidateException("frozenBalance must be more than 1TRX");
throw new ContractValidateException("frozenBalance must be greater than or equal to 1 TRX");
}

if (frozenBalance > accountCapsule.getBalance()) {
throw new ContractValidateException("frozenBalance must be less than accountBalance");
throw new ContractValidateException("frozenBalance must be less than or equal to accountBalance");
}

switch (freezeBalanceV2Contract.getResource()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.util.Arrays;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.tron.common.utils.DecodeUtil;
import org.tron.common.utils.StringUtil;
import org.tron.core.capsule.AccountCapsule;
Expand Down Expand Up @@ -144,9 +143,8 @@ public boolean execute(Object result) throws ContractExeException {

long now = chainBaseManager.getHeadSlot();
if (Objects.nonNull(receiverCapsule) && transferUsage > 0) {
ownerCapsule.setNetUsage(processor.unDelegateIncrease(ownerCapsule, receiverCapsule,
transferUsage, BANDWIDTH, now));
ownerCapsule.setLatestConsumeTime(now);
processor.unDelegateIncrease(ownerCapsule, receiverCapsule,
transferUsage, BANDWIDTH, now);
}
}
break;
Expand All @@ -160,9 +158,7 @@ public boolean execute(Object result) throws ContractExeException {

long now = chainBaseManager.getHeadSlot();
if (Objects.nonNull(receiverCapsule) && transferUsage > 0) {
ownerCapsule.setEnergyUsage(processor.unDelegateIncrease(ownerCapsule, receiverCapsule,
transferUsage, ENERGY, now));
ownerCapsule.setLatestConsumeTimeForEnergy(now);
processor.unDelegateIncrease(ownerCapsule, receiverCapsule, transferUsage, ENERGY, now);
}
}
break;
Expand Down Expand Up @@ -240,7 +236,7 @@ public boolean validate() throws ContractValidateException {
}

byte[] receiverAddress = unDelegateResourceContract.getReceiverAddress().toByteArray();
if (ArrayUtils.isEmpty(receiverAddress) || !DecodeUtil.addressValid(receiverAddress)) {
if (!DecodeUtil.addressValid(receiverAddress)) {
throw new ContractValidateException("Invalid receiverAddress");
}
if (Arrays.equals(receiverAddress, ownerAddress)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import com.google.common.collect.Lists;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -365,19 +367,23 @@ private void updateVote(AccountCapsule accountCapsule,
}

// Update Owner Voting
votesCapsule.clearNewVotes();
List<Vote> addVotes = new ArrayList<>();
for (Vote vote : accountCapsule.getVotesList()) {
long newVoteCount = (long)
((double) vote.getVoteCount() / totalVote * ownedTronPower / TRX_PRECISION);
if (newVoteCount > 0) {
votesCapsule.addNewVotes(vote.getVoteAddress(), newVoteCount);
Vote newVote = Vote.newBuilder()
.setVoteAddress(vote.getVoteAddress())
.setVoteCount(newVoteCount)
.build();
addVotes.add(newVote);
}
}
votesCapsule.clearNewVotes();
votesCapsule.addAllNewVotes(addVotes);
votesStore.put(ownerAddress, votesCapsule);

accountCapsule.clearVotes();
for (Vote vote : votesCapsule.getNewVotes()) {
accountCapsule.addVotes(vote.getVoteAddress(), vote.getVoteCount());
}
accountCapsule.addAllVotes(addVotes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ private long getTotalWithdrawUnfreeze(List<UnFreezeV2> unfrozenV2List, long now)
}

private List<UnFreezeV2> getTotalWithdrawList(List<UnFreezeV2> unfrozenV2List, long now) {
return unfrozenV2List.stream().filter(unfrozenV2 -> (unfrozenV2.getUnfreezeAmount() > 0
&& unfrozenV2.getUnfreezeExpireTime() <= now)).collect(Collectors.toList());
return unfrozenV2List.stream().filter(unfrozenV2 -> unfrozenV2.getUnfreezeExpireTime() <= now)
.collect(Collectors.toList());
}

private List<UnFreezeV2> getRemainWithdrawList(List<UnFreezeV2> unfrozenV2List, long now) {
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
57 changes: 13 additions & 44 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,56 +254,24 @@ public TransactionSignWeight getTransactionSignWeight(Transaction trx) {
return tswBuilder.build();
}

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;
}

}
Loading

0 comments on commit a02fbb0

Please sign in to comment.