Skip to content

Commit b30fd81

Browse files
committed
feat(freezeV2): optimize delegate resource lock period
1 parent 3c82c2a commit b30fd81

File tree

13 files changed

+509
-157
lines changed

13 files changed

+509
-157
lines changed

actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import static org.tron.core.actuator.ActuatorConstant.NOT_EXIST_STR;
44
import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_PERIOD;
5+
import static org.tron.core.config.Parameter.ChainConstant.MAX_BLOCK_NUM_DELEGATE_PERIOD;
56
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;
7+
import static org.tron.protos.contract.Common.ResourceCode;
8+
import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH;
9+
import static org.tron.protos.contract.Common.ResourceCode.ENERGY;
610

711
import com.google.protobuf.ByteString;
812
import com.google.protobuf.InvalidProtocolBufferException;
@@ -46,8 +50,10 @@ public boolean execute(Object result) throws ContractExeException {
4650
long fee = calcFee();
4751
final DelegateResourceContract delegateResourceContract;
4852
AccountStore accountStore = chainBaseManager.getAccountStore();
53+
byte[] ownerAddress;
4954
try {
50-
delegateResourceContract = any.unpack(DelegateResourceContract.class);
55+
delegateResourceContract = this.any.unpack(DelegateResourceContract.class);
56+
ownerAddress = getOwnerAddress().toByteArray();
5157
} catch (InvalidProtocolBufferException e) {
5258
logger.debug(e.getMessage(), e);
5359
ret.setStatus(fee, code.FAILED);
@@ -59,21 +65,21 @@ public boolean execute(Object result) throws ContractExeException {
5965

6066
long delegateBalance = delegateResourceContract.getBalance();
6167
boolean lock = delegateResourceContract.getLock();
62-
byte[] ownerAddress = delegateResourceContract.getOwnerAddress().toByteArray();
68+
long lockPeriod = delegateResourceContract.getLockPeriod();
6369
byte[] receiverAddress = delegateResourceContract.getReceiverAddress().toByteArray();
6470

6571
// delegate resource to receiver
6672
switch (delegateResourceContract.getResource()) {
6773
case BANDWIDTH:
6874
delegateResource(ownerAddress, receiverAddress, true,
69-
delegateBalance, lock);
75+
delegateBalance, lock, lockPeriod);
7076

7177
ownerCapsule.addDelegatedFrozenV2BalanceForBandwidth(delegateBalance);
7278
ownerCapsule.addFrozenBalanceForBandwidthV2(-delegateBalance);
7379
break;
7480
case ENERGY:
7581
delegateResource(ownerAddress, receiverAddress, false,
76-
delegateBalance, lock);
82+
delegateBalance, lock, lockPeriod);
7783

7884
ownerCapsule.addDelegatedFrozenV2BalanceForEnergy(delegateBalance);
7985
ownerCapsule.addFrozenBalanceForEnergyV2(-delegateBalance);
@@ -100,6 +106,7 @@ public boolean validate() throws ContractValidateException {
100106
}
101107
AccountStore accountStore = chainBaseManager.getAccountStore();
102108
DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore();
109+
DelegatedResourceStore delegatedResourceStore = chainBaseManager.getDelegatedResourceStore();
103110
if (!any.is(DelegateResourceContract.class)) {
104111
throw new ContractValidateException(
105112
"contract type error,expected type [DelegateResourceContract],real type["
@@ -116,13 +123,14 @@ public boolean validate() throws ContractValidateException {
116123
}
117124

118125
final DelegateResourceContract delegateResourceContract;
126+
byte[] ownerAddress;
119127
try {
120128
delegateResourceContract = this.any.unpack(DelegateResourceContract.class);
129+
ownerAddress = getOwnerAddress().toByteArray();
121130
} catch (InvalidProtocolBufferException e) {
122131
logger.debug(e.getMessage(), e);
123132
throw new ContractValidateException(e.getMessage());
124133
}
125-
byte[] ownerAddress = delegateResourceContract.getOwnerAddress().toByteArray();
126134
if (!DecodeUtil.addressValid(ownerAddress)) {
127135
throw new ContractValidateException("Invalid address");
128136
}
@@ -210,6 +218,36 @@ public boolean validate() throws ContractValidateException {
210218
+ readableOwnerAddress + NOT_EXIST_STR);
211219
}
212220

221+
boolean lock = delegateResourceContract.getLock();
222+
if (lock && dynamicStore.supportAllowOptimizeLockDelegateResource()) {
223+
long lockPeriod = delegateResourceContract.getLockPeriod();
224+
if (lockPeriod < 0 || lockPeriod > MAX_BLOCK_NUM_DELEGATE_PERIOD) {
225+
throw new ContractValidateException(
226+
"The lock period of delegate resource cannot be less than 0 and cannot exceed 1 year!");
227+
}
228+
229+
byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, true);
230+
DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore.get(key);
231+
long now = dynamicStore.getLatestBlockHeaderTimestamp();
232+
if (delegatedResourceCapsule != null) {
233+
switch (delegateResourceContract.getResource()) {
234+
case BANDWIDTH: {
235+
validRemainTime(BANDWIDTH, lockPeriod,
236+
delegatedResourceCapsule.getExpireTimeForBandwidth(), now);
237+
}
238+
break;
239+
case ENERGY: {
240+
validRemainTime(ENERGY, lockPeriod,
241+
delegatedResourceCapsule.getExpireTimeForEnergy(), now);
242+
}
243+
break;
244+
default:
245+
throw new ContractValidateException(
246+
"ResourceCode error, valid ResourceCode[BANDWIDTH、ENERGY]");
247+
}
248+
}
249+
}
250+
213251
if (receiverCapsule.getType() == AccountType.Contract) {
214252
throw new ContractValidateException(
215253
"Do not allow delegate resources to contract addresses");
@@ -218,6 +256,17 @@ public boolean validate() throws ContractValidateException {
218256
return true;
219257
}
220258

259+
private void validRemainTime(ResourceCode resourceCode, long lockPeriod, long expireTime,
260+
long now) throws ContractValidateException {
261+
long remainTime = expireTime - now;
262+
if (lockPeriod * 3 * 1000 < remainTime) {
263+
throw new ContractValidateException(
264+
"The lock period for " + resourceCode.name() + " this time cannot be less than the "
265+
+ "remaining time[" + remainTime + "s] of the last lock period for "
266+
+ resourceCode.name() + "!");
267+
}
268+
}
269+
221270
@Override
222271
public ByteString getOwnerAddress() throws InvalidProtocolBufferException {
223272
return any.unpack(DelegateResourceContract.class).getOwnerAddress();
@@ -229,7 +278,7 @@ public long calcFee() {
229278
}
230279

231280
private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boolean isBandwidth,
232-
long balance, boolean lock) {
281+
long balance, boolean lock, long lockPeriod) {
233282
AccountStore accountStore = chainBaseManager.getAccountStore();
234283
DynamicPropertiesStore dynamicPropertiesStore = chainBaseManager.getDynamicPropertiesStore();
235284
DelegatedResourceStore delegatedResourceStore = chainBaseManager.getDelegatedResourceStore();
@@ -241,12 +290,15 @@ private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boole
241290
delegatedResourceStore.unLockExpireResource(ownerAddress, receiverAddress, now);
242291

243292
//modify DelegatedResourceStore
244-
byte[] key;
245293
long expireTime = 0;
246294
if (lock) {
247-
expireTime = now + DELEGATE_PERIOD;
295+
if (dynamicPropertiesStore.supportAllowOptimizeLockDelegateResource()) {
296+
expireTime = now + (lockPeriod == 0 ? DELEGATE_PERIOD : lockPeriod * 3 * 1000);
297+
} else {
298+
expireTime = now + DELEGATE_PERIOD;
299+
}
248300
}
249-
key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, lock);
301+
byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, lock);
250302
DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore.get(key);
251303
if (delegatedResourceCapsule == null) {
252304
delegatedResourceCapsule = new DelegatedResourceCapsule(ByteString.copyFrom(ownerAddress),

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

Lines changed: 18 additions & 1 deletion
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_OPTIMIZE_LOCK_DELEGATE_RESOURCE: {
696+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_2)) {
697+
throw new ContractValidateException(
698+
"Bad chain parameter id [ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE]");
699+
}
700+
if (value != 1) {
701+
throw new ContractValidateException(
702+
"This value[ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE] 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_OPTIMIZE_LOCK_DELEGATE_RESOURCE] can be proposed");
708+
}
709+
break;
710+
}
695711
default:
696712
break;
697713
}
@@ -765,7 +781,8 @@ public enum ProposalType { // current value, value range
765781
DYNAMIC_ENERGY_THRESHOLD(73), // 0, [0, LONG]
766782
DYNAMIC_ENERGY_INCREASE_FACTOR(74), // 0, [0, 10_000]
767783
DYNAMIC_ENERGY_MAX_FACTOR(75), // 0, [0, 100_000]
768-
ALLOW_TVM_SHANGHAI(76); // 0, 1
784+
ALLOW_TVM_SHANGHAI(76), // 0, 1
785+
ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE(78); // 0, 1
769786

770787
private long code;
771788

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static org.tron.common.crypto.Hash.sha3omit12;
1919
import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_COST_BASE_SIZE;
20+
import static org.tron.core.config.Parameter.ChainConstant.MAX_BLOCK_NUM_DELEGATE_PERIOD;
2021
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;
2122

2223
import com.google.common.base.CaseFormat;
@@ -279,11 +280,11 @@ public static long consumeBandWidthSize(
279280
}
280281

281282

282-
public static long estimateConsumeBandWidthSize(
283-
final AccountCapsule ownerCapsule,
284-
ChainBaseManager chainBaseManager) {
283+
public static long estimateConsumeBandWidthSize(final AccountCapsule ownerCapsule,
284+
ChainBaseManager chainBaseManager) {
285285
DelegateResourceContract.Builder builder = DelegateResourceContract.newBuilder()
286286
.setLock(true)
287+
.setLockPeriod(MAX_BLOCK_NUM_DELEGATE_PERIOD)
287288
.setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth());
288289
TransactionCapsule fakeTransactionCapsule = new TransactionCapsule(builder.build()
289290
, ContractType.DelegateResourceContract);

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import org.tron.common.utils.ByteArray;
1515
import org.tron.common.utils.Sha256Hash;
1616
import org.tron.core.capsule.BytesCapsule;
17-
import org.tron.core.config.Parameter;
1817
import org.tron.core.config.Parameter.ChainConstant;
1918
import org.tron.core.db.TronStoreWithRevoking;
2019
import org.tron.core.exception.BadItemException;
@@ -208,6 +207,9 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>
208207

209208
private static final byte[] ALLOW_TVM_SHANGHAI = "ALLOW_TVM_SHANGHAI".getBytes();
210209

210+
private static final byte[] ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE =
211+
"ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE".getBytes();
212+
211213
@Autowired
212214
private DynamicPropertiesStore(@Value("properties") String dbName) {
213215
super(dbName);
@@ -2192,7 +2194,7 @@ public long getNextMaintenanceTime() {
21922194
}
21932195

21942196
public long getMaintenanceSkipSlots() {
2195-
return Parameter.ChainConstant.MAINTENANCE_SKIP_SLOTS;
2197+
return ChainConstant.MAINTENANCE_SKIP_SLOTS;
21962198
}
21972199

21982200
public void saveNextMaintenanceTime(long nextMaintenanceTime) {
@@ -2218,6 +2220,9 @@ public void updateNextMaintenanceTime(long blockTime) {
22182220

22192221
//The unit is trx
22202222
public void addTotalNetWeight(long amount) {
2223+
if (amount == 0) {
2224+
return;
2225+
}
22212226
long totalNetWeight = getTotalNetWeight();
22222227
totalNetWeight += amount;
22232228
if (allowNewReward()) {
@@ -2228,6 +2233,9 @@ public void addTotalNetWeight(long amount) {
22282233

22292234
//The unit is trx
22302235
public void addTotalEnergyWeight(long amount) {
2236+
if (amount == 0) {
2237+
return;
2238+
}
22312239
long totalEnergyWeight = getTotalEnergyWeight();
22322240
totalEnergyWeight += amount;
22332241
if (allowNewReward()) {
@@ -2238,6 +2246,9 @@ public void addTotalEnergyWeight(long amount) {
22382246

22392247
//The unit is trx
22402248
public void addTotalTronPowerWeight(long amount) {
2249+
if (amount == 0) {
2250+
return;
2251+
}
22412252
long totalWeight = getTotalTronPowerWeight();
22422253
totalWeight += amount;
22432254
if (allowNewReward()) {
@@ -2769,6 +2780,22 @@ public long getAllowTvmShangHai() {
27692780
.orElse(CommonParameter.getInstance().getAllowTvmShangHai());
27702781
}
27712782

2783+
public void saveAllowOptimizeLockDelegateResource(long allowOptimizeLockDelegateResource) {
2784+
this.put(DynamicPropertiesStore.ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE,
2785+
new BytesCapsule(ByteArray.fromLong(allowOptimizeLockDelegateResource)));
2786+
}
2787+
2788+
public long getAllowOptimizeLockDelegateResource() {
2789+
return Optional.ofNullable(getUnchecked(ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE))
2790+
.map(BytesCapsule::getData)
2791+
.map(ByteArray::toLong)
2792+
.orElse(CommonParameter.getInstance().getAllowOptimizeLockDelegateResource());
2793+
}
2794+
2795+
public boolean supportAllowOptimizeLockDelegateResource() {
2796+
return getAllowOptimizeLockDelegateResource() == 1L;
2797+
}
2798+
27722799
private static class DynamicResourceProperties {
27732800

27742801
private static final byte[] ONE_DAY_NET_LIMIT = "ONE_DAY_NET_LIMIT".getBytes();

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 allowOptimizeLockDelegateResource;
657+
654658
private static double calcMaxTimeRatio() {
655659
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
656660
return 5.0;

common/src/main/java/org/tron/core/config/Parameter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public class ChainConstant {
7474
public static final int BLOCK_VERSION = 28;
7575
public static final long FROZEN_PERIOD = 86_400_000L;
7676
public static final long DELEGATE_PERIOD = 3 * 86_400_000L;
77+
public static final long MAX_BLOCK_NUM_DELEGATE_PERIOD = 10512000L;
7778
public static final long TRX_PRECISION = 1000_000L;
7879
public static final long DELEGATE_COST_BASE_SIZE = 275L;
7980
}

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("getAllowOptimizeLockDelegateResource")
1330+
.setValue(dbManager.getDynamicPropertiesStore().getAllowOptimizeLockDelegateResource())
1331+
.build());
1332+
13281333
return builder.build();
13291334
}
13301335

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,13 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule)
343343
manager.getDynamicPropertiesStore().saveAllowTvmShangHai(entry.getValue());
344344
break;
345345
}
346+
case ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE: {
347+
if (manager.getDynamicPropertiesStore().getAllowOptimizeLockDelegateResource() == 0) {
348+
manager.getDynamicPropertiesStore()
349+
.saveAllowOptimizeLockDelegateResource(entry.getValue());
350+
}
351+
break;
352+
}
346353
default:
347354
find = false;
348355
break;

framework/src/main/java/org/tron/core/services/http/DelegateResourceServlet.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.tron.core.services.http;
22

3+
import com.alibaba.fastjson.JSON;
34
import com.alibaba.fastjson.JSONObject;
45
import javax.servlet.http.HttpServletRequest;
56
import javax.servlet.http.HttpServletResponse;
@@ -18,6 +19,7 @@ public class DelegateResourceServlet extends RateLimiterServlet {
1819
@Autowired
1920
private Wallet wallet;
2021

22+
@Override
2123
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
2224
try {
2325
PostParams params = PostParams.getPostParams(request);
@@ -26,7 +28,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
2628
Transaction tx = wallet
2729
.createTransactionCapsule(build.build(), ContractType.DelegateResourceContract)
2830
.getInstance();
29-
JSONObject jsonObject = JSONObject.parseObject(params.getParams());
31+
JSONObject jsonObject = JSON.parseObject(params.getParams());
3032
tx = Util.setTransactionPermissionId(jsonObject, tx);
3133
response.getWriter().println(Util.printCreateTransaction(tx, params.isVisible()));
3234
} catch (Exception e) {

0 commit comments

Comments
 (0)