Skip to content

Commit 16ba088

Browse files
authored
Merge pull request #5255 from lxcmyf/release_4.7.2
feat(freezeV2): optimize delegate resource lock period
2 parents b15bcd5 + fd68f94 commit 16ba088

13 files changed

Lines changed: 501 additions & 155 deletions

File tree

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
@@ -708,6 +708,22 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
708708
}
709709
break;
710710
}
711+
case ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE: {
712+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_2)) {
713+
throw new ContractValidateException(
714+
"Bad chain parameter id [ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE]");
715+
}
716+
if (value != 1) {
717+
throw new ContractValidateException(
718+
"This value[ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE] is only allowed to be 1");
719+
}
720+
if (dynamicPropertiesStore.getUnfreezeDelayDays() == 0) {
721+
throw new ContractValidateException(
722+
"[UNFREEZE_DELAY_DAYS] proposal must be approved "
723+
+ "before [ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE] can be proposed");
724+
}
725+
break;
726+
}
711727
default:
712728
break;
713729
}
@@ -782,7 +798,8 @@ 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
785-
ALLOW_CANCEL_UNFREEZE_V2(77); // 0, 1
801+
ALLOW_CANCEL_UNFREEZE_V2(77), // 0, 1
802+
ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE(78); // 0, 1
786803

787804
private long code;
788805

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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>
210210
private static final byte[] ALLOW_CANCEL_UNFREEZE_V2 = "ALLOW_CANCEL_UNFREEZE_V2"
211211
.getBytes();
212212

213+
private static final byte[] ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE =
214+
"ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE".getBytes();
215+
213216
@Autowired
214217
private DynamicPropertiesStore(@Value("properties") String dbName) {
215218
super(dbName);
@@ -2796,6 +2799,22 @@ public boolean supportAllowCancelUnfreezeV2() {
27962799
return getAllowCancelUnfreezeV2() == 1L && getUnfreezeDelayDays() > 0;
27972800
}
27982801

2802+
public void saveAllowOptimizeLockDelegateResource(long allowOptimizeLockDelegateResource) {
2803+
this.put(DynamicPropertiesStore.ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE,
2804+
new BytesCapsule(ByteArray.fromLong(allowOptimizeLockDelegateResource)));
2805+
}
2806+
2807+
public long getAllowOptimizeLockDelegateResource() {
2808+
return Optional.ofNullable(getUnchecked(ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE))
2809+
.map(BytesCapsule::getData)
2810+
.map(ByteArray::toLong)
2811+
.orElse(CommonParameter.getInstance().getAllowOptimizeLockDelegateResource());
2812+
}
2813+
2814+
public boolean supportAllowOptimizeLockDelegateResource() {
2815+
return getAllowOptimizeLockDelegateResource() == 1L && getUnfreezeDelayDays() > 0;
2816+
}
2817+
27992818
private static class DynamicResourceProperties {
28002819

28012820
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
@@ -655,6 +655,10 @@ public class CommonParameter {
655655
@Setter
656656
public long allowCancelUnfreezeV2;
657657

658+
@Getter
659+
@Setter
660+
public long allowOptimizeLockDelegateResource;
661+
658662
private static double calcMaxTimeRatio() {
659663
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
660664
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
@@ -1330,6 +1330,11 @@ public Protocol.ChainParameters getChainParameters() {
13301330
.setValue(dbManager.getDynamicPropertiesStore().getAllowCancelUnfreezeV2())
13311331
.build());
13321332

1333+
builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder()
1334+
.setKey("getAllowOptimizeLockDelegateResource")
1335+
.setValue(dbManager.getDynamicPropertiesStore().getAllowOptimizeLockDelegateResource())
1336+
.build());
1337+
13331338
return builder.build();
13341339
}
13351340

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,13 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule)
351351
}
352352
break;
353353
}
354+
case ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE: {
355+
if (manager.getDynamicPropertiesStore().getAllowOptimizeLockDelegateResource() == 0) {
356+
manager.getDynamicPropertiesStore()
357+
.saveAllowOptimizeLockDelegateResource(entry.getValue());
358+
}
359+
break;
360+
}
354361
default:
355362
find = false;
356363
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) {

framework/src/test/java/org/tron/core/WalletTest.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ public void testGetEcKey() {
363363
public void ss() {
364364
for (int i = 0; i < 4; i++) {
365365
ECKey ecKey = new ECKey(Utils.getRandom());
366+
assertNotNull(ecKey);
366367
System.out.println(i + 1);
367368
System.out.println("privateKey:" + ByteArray.toHexString(ecKey.getPrivKeyBytes()));
368369
System.out.println("publicKey:" + ByteArray.toHexString(ecKey.getPubKey()));
@@ -483,14 +484,14 @@ public void getPaginatedAssetIssueList() {
483484
AssetIssueList assetList1 = wallet.getAssetIssueList(0, 100);
484485
assertEquals("get Asset1", assetList1.getAssetIssue(0).getName(), Asset1.getName());
485486
try {
486-
assetList1.getAssetIssue(1);
487+
assertNotNull(assetList1.getAssetIssue(1));
487488
} catch (Exception e) {
488489
Assert.assertTrue("AssetIssueList1 size should be 1", true);
489490
}
490491

491492
AssetIssueList assetList2 = wallet.getAssetIssueList(0, 0);
492493
try {
493-
assetList2.getAssetIssue(0);
494+
assertNotNull(assetList2.getAssetIssue(0));
494495
} catch (Exception e) {
495496
Assert.assertTrue("AssetIssueList2 size should be 0", true);
496497
}
@@ -615,12 +616,8 @@ public void testGetDelegatedResource() {
615616
delegatedResourceList.getDelegatedResource(0).getFrozenBalanceForBandwidth());
616617
Assert.assertEquals(0L,
617618
delegatedResourceList.getDelegatedResource(0).getExpireTimeForBandwidth());
618-
} catch (ContractValidateException e) {
619-
Assert.assertFalse(e instanceof ContractValidateException);
620-
} catch (ContractExeException e) {
621-
Assert.assertFalse(e instanceof ContractExeException);
622619
} catch (Exception e) {
623-
Assert.assertEquals(false, true);
620+
Assert.fail();
624621
}
625622
}
626623

@@ -794,7 +791,7 @@ public void testGetCanDelegatedMaxSizeBandWidth() {
794791
GrpcAPI.CanDelegatedMaxSizeResponseMessage message = wallet.getCanDelegatedMaxSize(
795792
ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)),
796793
BANDWIDTH.getNumber());
797-
Assert.assertEquals(initBalance - 280L, message.getMaxSize());
794+
Assert.assertEquals(initBalance - 285L, message.getMaxSize());
798795

799796
}
800797

@@ -1054,13 +1051,13 @@ public void testEstimateEnergyOutOfTime() {
10541051
@Test
10551052
public void testListNodes() {
10561053
try {
1057-
GrpcAPI.NodeList nodeList = wallet.listNodes();
1054+
wallet.listNodes();
10581055
} catch (Exception e) {
10591056
Assert.assertTrue(e instanceof NullPointerException);
10601057
}
10611058
Args.getInstance().setP2pDisable(true);
10621059
GrpcAPI.NodeList nodeList = wallet.listNodes();
1063-
Assert.assertTrue(nodeList.getNodesList().size() == 0);
1060+
assertEquals(0, nodeList.getNodesList().size());
10641061
}
10651062
}
10661063

0 commit comments

Comments
 (0)