Skip to content

feat(freezeV2): optimize Stake 2.0 APIs #5260

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,5 @@ Wallet

# vm_trace
/vm_trace/

/framework/propPath
4 changes: 2 additions & 2 deletions Tron protobuf protocol document.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ Transaction and transaction-related messages.
WithdrawExpireUnfreezeContract = 56;
DelegateResourceContract = 57;
UnDelegateResourceContract = 58;
CancelUnfreezeV2Contract = 59;
CancelAllUnfreezeV2Contract = 59;
}
ContractType type = 1;
google.protobuf.Any parameter = 2;
Expand Down Expand Up @@ -888,7 +888,7 @@ Contract and contract-related messages.
WithdrawExpireUnfreezeContract = 56;
DelegateResourceContract = 57;
UnDelegateResourceContract = 58;
CancelUnfreezeV2Contract = 59;
CancelAllUnfreezeV2Contract = 59;
}
ContractType type = 1;
google.protobuf.Any parameter = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@

import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.tron.common.utils.DecodeUtil;
import org.tron.common.utils.StringUtil;
Expand All @@ -28,13 +24,13 @@
import org.tron.protos.Protocol.Account.UnFreezeV2;
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
import org.tron.protos.Protocol.Transaction.Result.code;
import org.tron.protos.contract.BalanceContract.CancelUnfreezeV2Contract;
import org.tron.protos.contract.BalanceContract.CancelAllUnfreezeV2Contract;

@Slf4j(topic = "actuator")
public class CancelUnfreezeV2Actuator extends AbstractActuator {
public class CancelAllUnfreezeV2Actuator extends AbstractActuator {

public CancelUnfreezeV2Actuator() {
super(ContractType.CancelUnfreezeV2Contract, CancelUnfreezeV2Contract.class);
public CancelAllUnfreezeV2Actuator() {
super(ContractType.CancelAllUnfreezeV2Contract, CancelAllUnfreezeV2Contract.class);
}

@Override
Expand All @@ -46,42 +42,26 @@ public boolean execute(Object result) throws ContractExeException {
long fee = calcFee();
AccountStore accountStore = chainBaseManager.getAccountStore();
DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore();
final CancelUnfreezeV2Contract cancelUnfreezeV2Contract;
byte[] ownerAddress;
try {
cancelUnfreezeV2Contract = getCancelUnfreezeV2Contract();
ownerAddress = getOwnerAddress().toByteArray();
} catch (InvalidProtocolBufferException e) {
logger.debug(e.getMessage(), e);
ret.setStatus(fee, code.FAILED);
throw new ContractExeException(e.getMessage());
}
List<Integer> indexList = cancelUnfreezeV2Contract.getIndexList()
.stream().sorted().collect(Collectors.toList());
AccountCapsule ownerCapsule = accountStore.get(ownerAddress);
List<UnFreezeV2> unfrozenV2List = ownerCapsule.getUnfrozenV2List();
long now = dynamicStore.getLatestBlockHeaderTimestamp();
AtomicLong atomicWithdrawExpireBalance = new AtomicLong(0L);
AtomicLong atomicCancelBalance = new AtomicLong(0L);
Triple<AtomicLong, AtomicLong, AtomicLong> triple =
Triple.of(new AtomicLong(0L), new AtomicLong(0L), new AtomicLong(0L));
List<UnFreezeV2> newUnFreezeV2List = null;
if (indexList.isEmpty()) {
for (UnFreezeV2 unFreezeV2 : unfrozenV2List) {
updateAndCalculate(triple, ownerCapsule, now, atomicWithdrawExpireBalance,
atomicCancelBalance, unFreezeV2);
}
} else {
indexList.forEach(index -> {
UnFreezeV2 unFreezeV2 = unfrozenV2List.get(index);
updateAndCalculate(triple, ownerCapsule, now, atomicWithdrawExpireBalance,
atomicCancelBalance, unFreezeV2);
});
newUnFreezeV2List = unfrozenV2List.stream()
.filter(o -> !indexList.contains(unfrozenV2List.indexOf(o))).collect(Collectors.toList());
for (UnFreezeV2 unFreezeV2 : unfrozenV2List) {
updateAndCalculate(triple, ownerCapsule, now, atomicWithdrawExpireBalance,
atomicCancelBalance, unFreezeV2);
}
ownerCapsule.clearUnfrozenV2();
ownerCapsule.addAllUnfrozenV2(newUnFreezeV2List);
addTotalResourceWeight(dynamicStore, triple);

long withdrawExpireBalance = atomicWithdrawExpireBalance.get();
Expand All @@ -91,7 +71,7 @@ public boolean execute(Object result) throws ContractExeException {

accountStore.put(ownerCapsule.createDbKey(), ownerCapsule);
ret.setWithdrawExpireAmount(withdrawExpireBalance);
ret.setCancelUnfreezeV2Amount(atomicCancelBalance.get());
ret.setCancelAllUnfreezeV2Amount(atomicCancelBalance.get());
ret.setStatus(fee, code.SUCESS);
return true;
}
Expand Down Expand Up @@ -127,20 +107,18 @@ public boolean validate() throws ContractValidateException {
AccountStore accountStore = chainBaseManager.getAccountStore();
DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore();

if (!this.any.is(CancelUnfreezeV2Contract.class)) {
if (!this.any.is(CancelAllUnfreezeV2Contract.class)) {
throw new ContractValidateException("contract type error, expected type " +
"[CancelUnfreezeV2Contract], real type[" + any.getClass() + "]");
"[CancelAllUnfreezeV2Contract], real type[" + any.getClass() + "]");
}

if (!dynamicStore.supportAllowCancelUnfreezeV2()) {
throw new ContractValidateException("Not support CancelUnfreezeV2 transaction,"
if (!dynamicStore.supportAllowCancelAllUnfreezeV2()) {
throw new ContractValidateException("Not support CancelAllUnfreezeV2 transaction,"
+ " need to be opened by the committee");
}

final CancelUnfreezeV2Contract cancelUnfreezeV2Contract;
byte[] ownerAddress;
try {
cancelUnfreezeV2Contract = getCancelUnfreezeV2Contract();
ownerAddress = getOwnerAddress().toByteArray();
} catch (InvalidProtocolBufferException e) {
logger.debug(e.getMessage(), e);
Expand All @@ -162,37 +140,17 @@ public boolean validate() throws ContractValidateException {
throw new ContractValidateException("No unfreezeV2 list to cancel");
}

List<Integer> indexList = cancelUnfreezeV2Contract.getIndexList();
if (indexList.size() > unfrozenV2List.size()) {
throw new ContractValidateException(
"The size[" + indexList.size() + "] of the index cannot exceed the size["
+ unfrozenV2List.size() + "] of unfreezeV2!");
}

for (Integer i : indexList) {
int maxIndex = unfrozenV2List.size() - 1;
if (i < 0 || i > maxIndex) {
throw new ContractValidateException(
"The input index[" + i + "] cannot be less than 0 and cannot be "
+ "greater than the maximum index[" + maxIndex + "] of unfreezeV2!");
}
}
Set<Integer> set = new HashSet<>();
List<Integer> dps = indexList.stream().filter(n -> !set.add(n)).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(dps)) {
throw new ContractValidateException("The element" + dps + " in the index list is duplicated");
}
return true;
}

@Override
public ByteString getOwnerAddress() throws InvalidProtocolBufferException {
return getCancelUnfreezeV2Contract().getOwnerAddress();
return getCancelAllUnfreezeV2Contract().getOwnerAddress();
}

private CancelUnfreezeV2Contract getCancelUnfreezeV2Contract()
private CancelAllUnfreezeV2Contract getCancelAllUnfreezeV2Contract()
throws InvalidProtocolBufferException {
return any.unpack(CancelUnfreezeV2Contract.class);
return any.unpack(CancelAllUnfreezeV2Contract.class);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static org.tron.core.actuator.ActuatorConstant.NOT_EXIST_STR;
import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_PERIOD;
import static org.tron.core.config.Parameter.ChainConstant.MAX_BLOCK_NUM_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;
Expand Down Expand Up @@ -219,11 +218,13 @@ public boolean validate() throws ContractValidateException {
}

boolean lock = delegateResourceContract.getLock();
if (lock && dynamicStore.supportAllowOptimizeLockDelegateResource()) {
if (lock && dynamicStore.supportMaxDelegateLockPeriod()) {
long lockPeriod = delegateResourceContract.getLockPeriod();
if (lockPeriod < 0 || lockPeriod > MAX_BLOCK_NUM_DELEGATE_PERIOD) {
long maxDelegateLockPeriod = dynamicStore.getMaxDelegateLockPeriod();
if (lockPeriod < 0 || lockPeriod > maxDelegateLockPeriod) {
throw new ContractValidateException(
"The lock period of delegate resource cannot be less than 0 and cannot exceed 1 year!");
"The lock period of delegate resource cannot be less than 0 and cannot exceed "
+ maxDelegateLockPeriod + "!");
}

byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, true);
Expand Down Expand Up @@ -262,7 +263,7 @@ private void validRemainTime(ResourceCode resourceCode, long lockPeriod, long ex
if (lockPeriod * 3 * 1000 < remainTime) {
throw new ContractValidateException(
"The lock period for " + resourceCode.name() + " this time cannot be less than the "
+ "remaining time[" + remainTime + "s] of the last lock period for "
+ "remaining time[" + remainTime + "ms] of the last lock period for "
+ resourceCode.name() + "!");
}
}
Expand Down Expand Up @@ -292,7 +293,7 @@ private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boole
//modify DelegatedResourceStore
long expireTime = 0;
if (lock) {
if (dynamicPropertiesStore.supportAllowOptimizeLockDelegateResource()) {
if (dynamicPropertiesStore.supportMaxDelegateLockPeriod()) {
expireTime = now + (lockPeriod == 0 ? DELEGATE_PERIOD : lockPeriod * 3 * 1000);
} else {
expireTime = now + DELEGATE_PERIOD;
Expand Down
23 changes: 12 additions & 11 deletions actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -692,35 +692,36 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
}
break;
}
case ALLOW_CANCEL_UNFREEZE_V2: {
case ALLOW_CANCEL_ALL_UNFREEZE_V2: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_2)) {
throw new ContractValidateException(
"Bad chain parameter id [ALLOW_CANCEL_UNFREEZE_V2]");
"Bad chain parameter id [ALLOW_CANCEL_ALL_UNFREEZE_V2]");
}
if (value != 1) {
throw new ContractValidateException(
"This value[ALLOW_CANCEL_UNFREEZE_V2] is only allowed to be 1");
"This value[ALLOW_CANCEL_ALL_UNFREEZE_V2] is only allowed to be 1");
}
if (dynamicPropertiesStore.getUnfreezeDelayDays() == 0) {
throw new ContractValidateException(
"[UNFREEZE_DELAY_DAYS] proposal must be approved "
+ "before [ALLOW_CANCEL_UNFREEZE_V2] can be proposed");
+ "before [ALLOW_CANCEL_ALL_UNFREEZE_V2] can be proposed");
}
break;
}
case ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE: {
case MAX_DELEGATE_LOCK_PERIOD: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_2)) {
throw new ContractValidateException(
"Bad chain parameter id [ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE]");
"Bad chain parameter id [MAX_DELEGATE_LOCK_PERIOD]");
}
if (value != 1) {
if (value <= 0) {
throw new ContractValidateException(
"This value[ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE] is only allowed to be 1");
"This value[MAX_DELEGATE_LOCK_PERIOD] is only allowed to be "
+ "greater than 0");
}
if (dynamicPropertiesStore.getUnfreezeDelayDays() == 0) {
throw new ContractValidateException(
"[UNFREEZE_DELAY_DAYS] proposal must be approved "
+ "before [ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE] can be proposed");
+ "before [MAX_DELEGATE_LOCK_PERIOD] can be proposed");
}
break;
}
Expand Down Expand Up @@ -798,8 +799,8 @@ public enum ProposalType { // current value, value range
DYNAMIC_ENERGY_INCREASE_FACTOR(74), // 0, [0, 10_000]
DYNAMIC_ENERGY_MAX_FACTOR(75), // 0, [0, 100_000]
ALLOW_TVM_SHANGHAI(76), // 0, 1
ALLOW_CANCEL_UNFREEZE_V2(77), // 0, 1
ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE(78); // 0, 1
ALLOW_CANCEL_ALL_UNFREEZE_V2(77), // 0, 1
MAX_DELEGATE_LOCK_PERIOD(78); // 0, 1

private long code;

Expand Down
17 changes: 11 additions & 6 deletions actuator/src/main/java/org/tron/core/utils/TransactionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import static org.tron.common.crypto.Hash.sha3omit12;
import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_COST_BASE_SIZE;
import static org.tron.core.config.Parameter.ChainConstant.MAX_BLOCK_NUM_DELEGATE_PERIOD;
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;

import com.google.common.base.CaseFormat;
Expand Down Expand Up @@ -279,13 +278,19 @@ public static long consumeBandWidthSize(
return bytesSize;
}


public static long estimateConsumeBandWidthSize(final AccountCapsule ownerCapsule,
ChainBaseManager chainBaseManager) {
DelegateResourceContract.Builder builder = DelegateResourceContract.newBuilder()
.setLock(true)
.setLockPeriod(MAX_BLOCK_NUM_DELEGATE_PERIOD)
.setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth());
DelegateResourceContract.Builder builder;
if (chainBaseManager.getDynamicPropertiesStore().supportMaxDelegateLockPeriod()) {
builder = DelegateResourceContract.newBuilder()
.setLock(true)
.setLockPeriod(chainBaseManager.getDynamicPropertiesStore().getMaxDelegateLockPeriod())
.setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth());
} else {
builder = DelegateResourceContract.newBuilder()
.setLock(true)
.setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth());
}
TransactionCapsule fakeTransactionCapsule = new TransactionCapsule(builder.build()
, ContractType.DelegateResourceContract);
long size1 = consumeBandWidthSize(fakeTransactionCapsule, chainBaseManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ public void setWithdrawExpireAmount(long amount) {
.setWithdrawExpireAmount(amount).build();
}

public long getCancelUnfreezeV2Amount() {
return transactionResult.getCancelUnfreezeV2Amount();
public long getCancelAllUnfreezeV2Amount() {
return transactionResult.getCancelAllUnfreezeV2Amount();
}

public void setCancelUnfreezeV2Amount(long amount) {
public void setCancelAllUnfreezeV2Amount(long amount) {
this.transactionResult = this.transactionResult.toBuilder()
.setCancelUnfreezeV2Amount(amount).build();
.setCancelAllUnfreezeV2Amount(amount).build();
}

public long getExchangeReceivedAmount() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public static TransactionInfoCapsule buildTransactionInfoInstance(TransactionCap
builder.setExchangeId(programResult.getRet().getExchangeId());
builder.setWithdrawAmount(programResult.getRet().getWithdrawAmount());
builder.setWithdrawExpireAmount(programResult.getRet().getWithdrawExpireAmount());
builder.setCancelUnfreezeV2Amount(programResult.getRet().getCancelUnfreezeV2Amount());
builder.setCancelAllUnfreezeV2Amount(programResult.getRet().getCancelAllUnfreezeV2Amount());
builder.setExchangeReceivedAmount(programResult.getRet().getExchangeReceivedAmount());
builder.setExchangeInjectAnotherAmount(programResult.getRet().getExchangeInjectAnotherAmount());
builder.setExchangeWithdrawAnotherAmount(
Expand Down
Loading