Skip to content

Commit fd68f94

Browse files
committed
Merge remote-tracking branch 'origin/release_v4.7.2' into release_4.7.2
# Conflicts: # actuator/src/main/java/org/tron/core/utils/ProposalUtil.java # chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java # common/src/main/java/org/tron/common/parameter/CommonParameter.java # framework/src/main/java/org/tron/core/Wallet.java # framework/src/main/java/org/tron/core/consensus/ProposalService.java
2 parents d8d2999 + b15bcd5 commit fd68f94

20 files changed

Lines changed: 675 additions & 23 deletions

File tree

Tron protobuf protocol document.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ Transaction and transaction-related messages.
627627
WithdrawExpireUnfreezeContract = 56;
628628
DelegateResourceContract = 57;
629629
UnDelegateResourceContract = 58;
630+
CancelUnfreezeV2Contract = 59;
630631
}
631632
ContractType type = 1;
632633
google.protobuf.Any parameter = 2;
@@ -887,6 +888,7 @@ Contract and contract-related messages.
887888
WithdrawExpireUnfreezeContract = 56;
888889
DelegateResourceContract = 57;
889890
UnDelegateResourceContract = 58;
891+
CancelUnfreezeV2Contract = 59;
890892
}
891893
ContractType type = 1;
892894
google.protobuf.Any parameter = 2;
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
package org.tron.core.actuator;
2+
3+
import static org.tron.core.actuator.ActuatorConstant.ACCOUNT_EXCEPTION_STR;
4+
import static org.tron.core.actuator.ActuatorConstant.NOT_EXIST_STR;
5+
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;
6+
import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH;
7+
import static org.tron.protos.contract.Common.ResourceCode.ENERGY;
8+
9+
import com.google.protobuf.ByteString;
10+
import com.google.protobuf.InvalidProtocolBufferException;
11+
import java.util.HashSet;
12+
import java.util.List;
13+
import java.util.Objects;
14+
import java.util.Set;
15+
import java.util.concurrent.atomic.AtomicLong;
16+
import java.util.stream.Collectors;
17+
import lombok.extern.slf4j.Slf4j;
18+
import org.apache.commons.collections4.CollectionUtils;
19+
import org.apache.commons.lang3.tuple.Triple;
20+
import org.tron.common.utils.DecodeUtil;
21+
import org.tron.common.utils.StringUtil;
22+
import org.tron.core.capsule.AccountCapsule;
23+
import org.tron.core.capsule.TransactionResultCapsule;
24+
import org.tron.core.exception.ContractExeException;
25+
import org.tron.core.exception.ContractValidateException;
26+
import org.tron.core.store.AccountStore;
27+
import org.tron.core.store.DynamicPropertiesStore;
28+
import org.tron.protos.Protocol.Account.UnFreezeV2;
29+
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
30+
import org.tron.protos.Protocol.Transaction.Result.code;
31+
import org.tron.protos.contract.BalanceContract.CancelUnfreezeV2Contract;
32+
33+
@Slf4j(topic = "actuator")
34+
public class CancelUnfreezeV2Actuator extends AbstractActuator {
35+
36+
public CancelUnfreezeV2Actuator() {
37+
super(ContractType.CancelUnfreezeV2Contract, CancelUnfreezeV2Contract.class);
38+
}
39+
40+
@Override
41+
public boolean execute(Object result) throws ContractExeException {
42+
TransactionResultCapsule ret = (TransactionResultCapsule) result;
43+
if (Objects.isNull(ret)) {
44+
throw new RuntimeException(ActuatorConstant.TX_RESULT_NULL);
45+
}
46+
long fee = calcFee();
47+
AccountStore accountStore = chainBaseManager.getAccountStore();
48+
DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore();
49+
final CancelUnfreezeV2Contract cancelUnfreezeV2Contract;
50+
byte[] ownerAddress;
51+
try {
52+
cancelUnfreezeV2Contract = getCancelUnfreezeV2Contract();
53+
ownerAddress = getOwnerAddress().toByteArray();
54+
} catch (InvalidProtocolBufferException e) {
55+
logger.debug(e.getMessage(), e);
56+
ret.setStatus(fee, code.FAILED);
57+
throw new ContractExeException(e.getMessage());
58+
}
59+
List<Integer> indexList = cancelUnfreezeV2Contract.getIndexList()
60+
.stream().sorted().collect(Collectors.toList());
61+
AccountCapsule ownerCapsule = accountStore.get(ownerAddress);
62+
List<UnFreezeV2> unfrozenV2List = ownerCapsule.getUnfrozenV2List();
63+
long now = dynamicStore.getLatestBlockHeaderTimestamp();
64+
AtomicLong atomicWithdrawExpireBalance = new AtomicLong(0L);
65+
AtomicLong atomicCancelBalance = new AtomicLong(0L);
66+
Triple<AtomicLong, AtomicLong, AtomicLong> triple =
67+
Triple.of(new AtomicLong(0L), new AtomicLong(0L), new AtomicLong(0L));
68+
List<UnFreezeV2> newUnFreezeV2List = null;
69+
if (indexList.isEmpty()) {
70+
for (UnFreezeV2 unFreezeV2 : unfrozenV2List) {
71+
updateAndCalculate(triple, ownerCapsule, now, atomicWithdrawExpireBalance,
72+
atomicCancelBalance, unFreezeV2);
73+
}
74+
} else {
75+
indexList.forEach(index -> {
76+
UnFreezeV2 unFreezeV2 = unfrozenV2List.get(index);
77+
updateAndCalculate(triple, ownerCapsule, now, atomicWithdrawExpireBalance,
78+
atomicCancelBalance, unFreezeV2);
79+
});
80+
newUnFreezeV2List = unfrozenV2List.stream()
81+
.filter(o -> !indexList.contains(unfrozenV2List.indexOf(o))).collect(Collectors.toList());
82+
}
83+
ownerCapsule.clearUnfrozenV2();
84+
ownerCapsule.addAllUnfrozenV2(newUnFreezeV2List);
85+
addTotalResourceWeight(dynamicStore, triple);
86+
87+
long withdrawExpireBalance = atomicWithdrawExpireBalance.get();
88+
if (withdrawExpireBalance > 0) {
89+
ownerCapsule.setBalance(ownerCapsule.getBalance() + withdrawExpireBalance);
90+
}
91+
92+
accountStore.put(ownerCapsule.createDbKey(), ownerCapsule);
93+
ret.setWithdrawExpireAmount(withdrawExpireBalance);
94+
ret.setCancelUnfreezeV2Amount(atomicCancelBalance.get());
95+
ret.setStatus(fee, code.SUCESS);
96+
return true;
97+
}
98+
99+
private void addTotalResourceWeight(DynamicPropertiesStore dynamicStore,
100+
Triple<AtomicLong, AtomicLong, AtomicLong> triple) {
101+
dynamicStore.addTotalNetWeight(triple.getLeft().get());
102+
dynamicStore.addTotalEnergyWeight(triple.getMiddle().get());
103+
dynamicStore.addTotalTronPowerWeight(triple.getRight().get());
104+
}
105+
106+
private void updateAndCalculate(Triple<AtomicLong, AtomicLong, AtomicLong> triple,
107+
AccountCapsule ownerCapsule, long now, AtomicLong atomicLong, AtomicLong cancelBalance,
108+
UnFreezeV2 unFreezeV2) {
109+
if (unFreezeV2.getUnfreezeExpireTime() > now) {
110+
updateFrozenInfoAndTotalResourceWeight(ownerCapsule, unFreezeV2, triple);
111+
cancelBalance.addAndGet(unFreezeV2.getUnfreezeAmount());
112+
} else {
113+
atomicLong.addAndGet(unFreezeV2.getUnfreezeAmount());
114+
}
115+
}
116+
117+
@Override
118+
public boolean validate() throws ContractValidateException {
119+
if (Objects.isNull(this.any)) {
120+
throw new ContractValidateException(ActuatorConstant.CONTRACT_NOT_EXIST);
121+
}
122+
123+
if (Objects.isNull(chainBaseManager)) {
124+
throw new ContractValidateException(ActuatorConstant.STORE_NOT_EXIST);
125+
}
126+
127+
AccountStore accountStore = chainBaseManager.getAccountStore();
128+
DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore();
129+
130+
if (!this.any.is(CancelUnfreezeV2Contract.class)) {
131+
throw new ContractValidateException("contract type error, expected type " +
132+
"[CancelUnfreezeV2Contract], real type[" + any.getClass() + "]");
133+
}
134+
135+
if (!dynamicStore.supportAllowCancelUnfreezeV2()) {
136+
throw new ContractValidateException("Not support CancelUnfreezeV2 transaction,"
137+
+ " need to be opened by the committee");
138+
}
139+
140+
final CancelUnfreezeV2Contract cancelUnfreezeV2Contract;
141+
byte[] ownerAddress;
142+
try {
143+
cancelUnfreezeV2Contract = getCancelUnfreezeV2Contract();
144+
ownerAddress = getOwnerAddress().toByteArray();
145+
} catch (InvalidProtocolBufferException e) {
146+
logger.debug(e.getMessage(), e);
147+
throw new ContractValidateException(e.getMessage());
148+
}
149+
150+
if (!DecodeUtil.addressValid(ownerAddress)) {
151+
throw new ContractValidateException("Invalid address");
152+
}
153+
AccountCapsule accountCapsule = accountStore.get(ownerAddress);
154+
String readableOwnerAddress = StringUtil.createReadableString(ownerAddress);
155+
if (Objects.isNull(accountCapsule)) {
156+
throw new ContractValidateException(ACCOUNT_EXCEPTION_STR
157+
+ readableOwnerAddress + NOT_EXIST_STR);
158+
}
159+
160+
List<UnFreezeV2> unfrozenV2List = accountCapsule.getUnfrozenV2List();
161+
if (unfrozenV2List.isEmpty()) {
162+
throw new ContractValidateException("No unfreezeV2 list to cancel");
163+
}
164+
165+
List<Integer> indexList = cancelUnfreezeV2Contract.getIndexList();
166+
if (indexList.size() > unfrozenV2List.size()) {
167+
throw new ContractValidateException(
168+
"The size[" + indexList.size() + "] of the index cannot exceed the size["
169+
+ unfrozenV2List.size() + "] of unfreezeV2!");
170+
}
171+
172+
for (Integer i : indexList) {
173+
int maxIndex = unfrozenV2List.size() - 1;
174+
if (i < 0 || i > maxIndex) {
175+
throw new ContractValidateException(
176+
"The input index[" + i + "] cannot be less than 0 and cannot be "
177+
+ "greater than the maximum index[" + maxIndex + "] of unfreezeV2!");
178+
}
179+
}
180+
Set<Integer> set = new HashSet<>();
181+
List<Integer> dps = indexList.stream().filter(n -> !set.add(n)).collect(Collectors.toList());
182+
if (CollectionUtils.isNotEmpty(dps)) {
183+
throw new ContractValidateException("The element" + dps + " in the index list is duplicated");
184+
}
185+
return true;
186+
}
187+
188+
@Override
189+
public ByteString getOwnerAddress() throws InvalidProtocolBufferException {
190+
return getCancelUnfreezeV2Contract().getOwnerAddress();
191+
}
192+
193+
private CancelUnfreezeV2Contract getCancelUnfreezeV2Contract()
194+
throws InvalidProtocolBufferException {
195+
return any.unpack(CancelUnfreezeV2Contract.class);
196+
}
197+
198+
@Override
199+
public long calcFee() {
200+
return 0;
201+
}
202+
203+
public void updateFrozenInfoAndTotalResourceWeight(
204+
AccountCapsule accountCapsule, UnFreezeV2 unFreezeV2,
205+
Triple<AtomicLong, AtomicLong, AtomicLong> triple) {
206+
switch (unFreezeV2.getType()) {
207+
case BANDWIDTH:
208+
long oldNetWeight = accountCapsule.getFrozenV2BalanceWithDelegated(BANDWIDTH) / TRX_PRECISION;
209+
accountCapsule.addFrozenBalanceForBandwidthV2(unFreezeV2.getUnfreezeAmount());
210+
long newNetWeight = accountCapsule.getFrozenV2BalanceWithDelegated(BANDWIDTH) / TRX_PRECISION;
211+
triple.getLeft().addAndGet(newNetWeight - oldNetWeight);
212+
break;
213+
case ENERGY:
214+
long oldEnergyWeight = accountCapsule.getFrozenV2BalanceWithDelegated(ENERGY) / TRX_PRECISION;
215+
accountCapsule.addFrozenBalanceForEnergyV2(unFreezeV2.getUnfreezeAmount());
216+
long newEnergyWeight = accountCapsule.getFrozenV2BalanceWithDelegated(ENERGY) / TRX_PRECISION;
217+
triple.getMiddle().addAndGet(newEnergyWeight - oldEnergyWeight);
218+
break;
219+
case TRON_POWER:
220+
long oldTPWeight = accountCapsule.getTronPowerFrozenV2Balance() / TRX_PRECISION;
221+
accountCapsule.addFrozenForTronPowerV2(unFreezeV2.getUnfreezeAmount());
222+
long newTPWeight = accountCapsule.getTronPowerFrozenV2Balance() / TRX_PRECISION;
223+
triple.getRight().addAndGet(newTPWeight - oldTPWeight);
224+
break;
225+
default:
226+
break;
227+
}
228+
}
229+
}

actuator/src/main/java/org/tron/core/utils/ProposalUtil.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,22 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
692692
}
693693
break;
694694
}
695+
case ALLOW_CANCEL_UNFREEZE_V2: {
696+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_2)) {
697+
throw new ContractValidateException(
698+
"Bad chain parameter id [ALLOW_CANCEL_UNFREEZE_V2]");
699+
}
700+
if (value != 1) {
701+
throw new ContractValidateException(
702+
"This value[ALLOW_CANCEL_UNFREEZE_V2] is only allowed to be 1");
703+
}
704+
if (dynamicPropertiesStore.getUnfreezeDelayDays() == 0) {
705+
throw new ContractValidateException(
706+
"[UNFREEZE_DELAY_DAYS] proposal must be approved "
707+
+ "before [ALLOW_CANCEL_UNFREEZE_V2] can be proposed");
708+
}
709+
break;
710+
}
695711
case ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE: {
696712
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_2)) {
697713
throw new ContractValidateException(
@@ -782,6 +798,7 @@ public enum ProposalType { // current value, value range
782798
DYNAMIC_ENERGY_INCREASE_FACTOR(74), // 0, [0, 10_000]
783799
DYNAMIC_ENERGY_MAX_FACTOR(75), // 0, [0, 100_000]
784800
ALLOW_TVM_SHANGHAI(76), // 0, 1
801+
ALLOW_CANCEL_UNFREEZE_V2(77), // 0, 1
785802
ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE(78); // 0, 1
786803

787804
private long code;

chainbase/src/main/java/org/tron/core/capsule/TransactionResultCapsule.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ public void setWithdrawExpireAmount(long amount) {
8989
.setWithdrawExpireAmount(amount).build();
9090
}
9191

92+
public long getCancelUnfreezeV2Amount() {
93+
return transactionResult.getCancelUnfreezeV2Amount();
94+
}
95+
96+
public void setCancelUnfreezeV2Amount(long amount) {
97+
this.transactionResult = this.transactionResult.toBuilder()
98+
.setCancelUnfreezeV2Amount(amount).build();
99+
}
100+
92101
public long getExchangeReceivedAmount() {
93102
return transactionResult.getExchangeReceivedAmount();
94103
}

chainbase/src/main/java/org/tron/core/capsule/utils/TransactionUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public static TransactionInfoCapsule buildTransactionInfoInstance(TransactionCap
100100
builder.setExchangeId(programResult.getRet().getExchangeId());
101101
builder.setWithdrawAmount(programResult.getRet().getWithdrawAmount());
102102
builder.setWithdrawExpireAmount(programResult.getRet().getWithdrawExpireAmount());
103+
builder.setCancelUnfreezeV2Amount(programResult.getRet().getCancelUnfreezeV2Amount());
103104
builder.setExchangeReceivedAmount(programResult.getRet().getExchangeReceivedAmount());
104105
builder.setExchangeInjectAnotherAmount(programResult.getRet().getExchangeInjectAnotherAmount());
105106
builder.setExchangeWithdrawAnotherAmount(

chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>
207207

208208
private static final byte[] ALLOW_TVM_SHANGHAI = "ALLOW_TVM_SHANGHAI".getBytes();
209209

210+
private static final byte[] ALLOW_CANCEL_UNFREEZE_V2 = "ALLOW_CANCEL_UNFREEZE_V2"
211+
.getBytes();
212+
210213
private static final byte[] ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE =
211214
"ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE".getBytes();
212215

@@ -2780,6 +2783,22 @@ public long getAllowTvmShangHai() {
27802783
.orElse(CommonParameter.getInstance().getAllowTvmShangHai());
27812784
}
27822785

2786+
public void saveAllowCancelUnfreezeV2(long allowCancelUnfreezeV2) {
2787+
this.put(DynamicPropertiesStore.ALLOW_CANCEL_UNFREEZE_V2,
2788+
new BytesCapsule(ByteArray.fromLong(allowCancelUnfreezeV2)));
2789+
}
2790+
2791+
public long getAllowCancelUnfreezeV2() {
2792+
return Optional.ofNullable(getUnchecked(ALLOW_CANCEL_UNFREEZE_V2))
2793+
.map(BytesCapsule::getData)
2794+
.map(ByteArray::toLong)
2795+
.orElse(CommonParameter.getInstance().getAllowCancelUnfreezeV2());
2796+
}
2797+
2798+
public boolean supportAllowCancelUnfreezeV2() {
2799+
return getAllowCancelUnfreezeV2() == 1L && getUnfreezeDelayDays() > 0;
2800+
}
2801+
27832802
public void saveAllowOptimizeLockDelegateResource(long allowOptimizeLockDelegateResource) {
27842803
this.put(DynamicPropertiesStore.ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE,
27852804
new BytesCapsule(ByteArray.fromLong(allowOptimizeLockDelegateResource)));

common/src/main/java/org/tron/common/parameter/CommonParameter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,10 @@ public class CommonParameter {
651651
@Setter
652652
public long allowTvmShangHai;
653653

654+
@Getter
655+
@Setter
656+
public long allowCancelUnfreezeV2;
657+
654658
@Getter
655659
@Setter
656660
public long allowOptimizeLockDelegateResource;

framework/src/main/java/org/tron/core/Wallet.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,11 @@ public Protocol.ChainParameters getChainParameters() {
13251325
.setValue(dbManager.getDynamicPropertiesStore().getAllowTvmShangHai())
13261326
.build());
13271327

1328+
builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder()
1329+
.setKey("getAllowCancelUnfreezeV2")
1330+
.setValue(dbManager.getDynamicPropertiesStore().getAllowCancelUnfreezeV2())
1331+
.build());
1332+
13281333
builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder()
13291334
.setKey("getAllowOptimizeLockDelegateResource")
13301335
.setValue(dbManager.getDynamicPropertiesStore().getAllowOptimizeLockDelegateResource())

framework/src/main/java/org/tron/core/consensus/ProposalService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,14 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule)
343343
manager.getDynamicPropertiesStore().saveAllowTvmShangHai(entry.getValue());
344344
break;
345345
}
346+
case ALLOW_CANCEL_UNFREEZE_V2: {
347+
if (manager.getDynamicPropertiesStore().getAllowCancelUnfreezeV2() == 0) {
348+
manager.getDynamicPropertiesStore().saveAllowCancelUnfreezeV2(entry.getValue());
349+
manager.getDynamicPropertiesStore().addSystemContractAndSetPermission(
350+
ContractType.CancelUnfreezeV2Contract_VALUE);
351+
}
352+
break;
353+
}
346354
case ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE: {
347355
if (manager.getDynamicPropertiesStore().getAllowOptimizeLockDelegateResource() == 0) {
348356
manager.getDynamicPropertiesStore()

framework/src/main/java/org/tron/core/services/RpcApiService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
import org.tron.protos.contract.BalanceContract.AccountBalanceRequest;
131131
import org.tron.protos.contract.BalanceContract.AccountBalanceResponse;
132132
import org.tron.protos.contract.BalanceContract.BlockBalanceTrace;
133+
import org.tron.protos.contract.BalanceContract.CancelUnfreezeV2Contract;
133134
import org.tron.protos.contract.BalanceContract.DelegateResourceContract;
134135
import org.tron.protos.contract.BalanceContract.FreezeBalanceContract;
135136
import org.tron.protos.contract.BalanceContract.TransferContract;
@@ -1471,6 +1472,13 @@ public void unDelegateResource(UnDelegateResourceContract request,
14711472
responseObserver);
14721473
}
14731474

1475+
@Override
1476+
public void cancelUnfreezeV2(CancelUnfreezeV2Contract request,
1477+
StreamObserver<TransactionExtention> responseObserver) {
1478+
createTransactionExtention(request, ContractType.CancelUnfreezeV2Contract,
1479+
responseObserver);
1480+
}
1481+
14741482
@Override
14751483
public void proposalCreate(ProposalCreateContract request,
14761484
StreamObserver<TransactionExtention> responseObserver) {

0 commit comments

Comments
 (0)