From 36054e7ac5c22c8320a0b6aa297eb9a9924d4c13 Mon Sep 17 00:00:00 2001 From: liuxincheng <lxcmyf@qq.com> Date: Fri, 2 Jun 2023 10:49:06 +0800 Subject: [PATCH] feat(freezeV2): optimize delegate resource lock period --- .../actuator/DelegateResourceActuator.java | 70 +++- .../org/tron/core/utils/ProposalUtil.java | 19 +- .../org/tron/core/utils/TransactionUtil.java | 7 +- .../core/store/DynamicPropertiesStore.java | 31 +- .../common/parameter/CommonParameter.java | 4 + .../java/org/tron/core/config/Parameter.java | 1 + .../src/main/java/org/tron/core/Wallet.java | 5 + .../tron/core/consensus/ProposalService.java | 7 + .../http/DelegateResourceServlet.java | 4 +- .../test/java/org/tron/core/WalletTest.java | 17 +- .../DelegateResourceActuatorTest.java | 383 ++++++++++++++---- .../actuator/utils/TransactionUtilTest.java | 119 ++++-- .../core/contract/balance_contract.proto | 1 + 13 files changed, 511 insertions(+), 157 deletions(-) diff --git a/actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java b/actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java index f91c147e3ee..d7dfcd5da14 100755 --- a/actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java @@ -2,7 +2,11 @@ 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; +import static org.tron.protos.contract.Common.ResourceCode.ENERGY; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; @@ -46,8 +50,10 @@ public boolean execute(Object result) throws ContractExeException { long fee = calcFee(); final DelegateResourceContract delegateResourceContract; AccountStore accountStore = chainBaseManager.getAccountStore(); + byte[] ownerAddress; try { - delegateResourceContract = any.unpack(DelegateResourceContract.class); + delegateResourceContract = this.any.unpack(DelegateResourceContract.class); + ownerAddress = getOwnerAddress().toByteArray(); } catch (InvalidProtocolBufferException e) { logger.debug(e.getMessage(), e); ret.setStatus(fee, code.FAILED); @@ -59,21 +65,21 @@ public boolean execute(Object result) throws ContractExeException { long delegateBalance = delegateResourceContract.getBalance(); boolean lock = delegateResourceContract.getLock(); - byte[] ownerAddress = delegateResourceContract.getOwnerAddress().toByteArray(); + long lockPeriod = delegateResourceContract.getLockPeriod(); byte[] receiverAddress = delegateResourceContract.getReceiverAddress().toByteArray(); // delegate resource to receiver switch (delegateResourceContract.getResource()) { case BANDWIDTH: delegateResource(ownerAddress, receiverAddress, true, - delegateBalance, lock); + delegateBalance, lock, lockPeriod); ownerCapsule.addDelegatedFrozenV2BalanceForBandwidth(delegateBalance); ownerCapsule.addFrozenBalanceForBandwidthV2(-delegateBalance); break; case ENERGY: delegateResource(ownerAddress, receiverAddress, false, - delegateBalance, lock); + delegateBalance, lock, lockPeriod); ownerCapsule.addDelegatedFrozenV2BalanceForEnergy(delegateBalance); ownerCapsule.addFrozenBalanceForEnergyV2(-delegateBalance); @@ -100,6 +106,7 @@ public boolean validate() throws ContractValidateException { } AccountStore accountStore = chainBaseManager.getAccountStore(); DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore(); + DelegatedResourceStore delegatedResourceStore = chainBaseManager.getDelegatedResourceStore(); if (!any.is(DelegateResourceContract.class)) { throw new ContractValidateException( "contract type error,expected type [DelegateResourceContract],real type[" @@ -116,13 +123,14 @@ public boolean validate() throws ContractValidateException { } final DelegateResourceContract delegateResourceContract; + byte[] ownerAddress; try { delegateResourceContract = this.any.unpack(DelegateResourceContract.class); + ownerAddress = getOwnerAddress().toByteArray(); } catch (InvalidProtocolBufferException e) { logger.debug(e.getMessage(), e); throw new ContractValidateException(e.getMessage()); } - byte[] ownerAddress = delegateResourceContract.getOwnerAddress().toByteArray(); if (!DecodeUtil.addressValid(ownerAddress)) { throw new ContractValidateException("Invalid address"); } @@ -210,6 +218,36 @@ public boolean validate() throws ContractValidateException { + readableOwnerAddress + NOT_EXIST_STR); } + boolean lock = delegateResourceContract.getLock(); + if (lock && dynamicStore.supportAllowOptimizeLockDelegateResource()) { + long lockPeriod = delegateResourceContract.getLockPeriod(); + if (lockPeriod < 0 || lockPeriod > MAX_BLOCK_NUM_DELEGATE_PERIOD) { + throw new ContractValidateException( + "The lock period of delegate resource cannot be less than 0 and cannot exceed 1 year!"); + } + + byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, true); + DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore.get(key); + long now = dynamicStore.getLatestBlockHeaderTimestamp(); + if (delegatedResourceCapsule != null) { + switch (delegateResourceContract.getResource()) { + case BANDWIDTH: { + validRemainTime(BANDWIDTH, lockPeriod, + delegatedResourceCapsule.getExpireTimeForBandwidth(), now); + } + break; + case ENERGY: { + validRemainTime(ENERGY, lockPeriod, + delegatedResourceCapsule.getExpireTimeForEnergy(), now); + } + break; + default: + throw new ContractValidateException( + "ResourceCode error, valid ResourceCode[BANDWIDTH、ENERGY]"); + } + } + } + if (receiverCapsule.getType() == AccountType.Contract) { throw new ContractValidateException( "Do not allow delegate resources to contract addresses"); @@ -218,6 +256,17 @@ public boolean validate() throws ContractValidateException { return true; } + private void validRemainTime(ResourceCode resourceCode, long lockPeriod, long expireTime, + long now) throws ContractValidateException { + long remainTime = expireTime - now; + 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 " + + resourceCode.name() + "!"); + } + } + @Override public ByteString getOwnerAddress() throws InvalidProtocolBufferException { return any.unpack(DelegateResourceContract.class).getOwnerAddress(); @@ -229,7 +278,7 @@ public long calcFee() { } private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boolean isBandwidth, - long balance, boolean lock) { + long balance, boolean lock, long lockPeriod) { AccountStore accountStore = chainBaseManager.getAccountStore(); DynamicPropertiesStore dynamicPropertiesStore = chainBaseManager.getDynamicPropertiesStore(); DelegatedResourceStore delegatedResourceStore = chainBaseManager.getDelegatedResourceStore(); @@ -241,12 +290,15 @@ private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boole delegatedResourceStore.unLockExpireResource(ownerAddress, receiverAddress, now); //modify DelegatedResourceStore - byte[] key; long expireTime = 0; if (lock) { - expireTime = now + DELEGATE_PERIOD; + if (dynamicPropertiesStore.supportAllowOptimizeLockDelegateResource()) { + expireTime = now + (lockPeriod == 0 ? DELEGATE_PERIOD : lockPeriod * 3 * 1000); + } else { + expireTime = now + DELEGATE_PERIOD; + } } - key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, lock); + byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, lock); DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore.get(key); if (delegatedResourceCapsule == null) { delegatedResourceCapsule = new DelegatedResourceCapsule(ByteString.copyFrom(ownerAddress), diff --git a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java index 9ab68cc1925..0fdb9234bad 100644 --- a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java +++ b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java @@ -692,6 +692,22 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore, } break; } + case ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE: { + if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_2)) { + throw new ContractValidateException( + "Bad chain parameter id [ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE]"); + } + if (value != 1) { + throw new ContractValidateException( + "This value[ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE] is only allowed to be 1"); + } + if (dynamicPropertiesStore.getUnfreezeDelayDays() == 0) { + throw new ContractValidateException( + "[UNFREEZE_DELAY_DAYS] proposal must be approved " + + "before [ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE] can be proposed"); + } + break; + } default: break; } @@ -765,7 +781,8 @@ public enum ProposalType { // current value, value range DYNAMIC_ENERGY_THRESHOLD(73), // 0, [0, LONG] 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_TVM_SHANGHAI(76), // 0, 1 + ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE(78); // 0, 1 private long code; diff --git a/actuator/src/main/java/org/tron/core/utils/TransactionUtil.java b/actuator/src/main/java/org/tron/core/utils/TransactionUtil.java index e5cffa49790..e8fe963f89b 100644 --- a/actuator/src/main/java/org/tron/core/utils/TransactionUtil.java +++ b/actuator/src/main/java/org/tron/core/utils/TransactionUtil.java @@ -17,6 +17,7 @@ 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; @@ -279,11 +280,11 @@ public static long consumeBandWidthSize( } - public static long estimateConsumeBandWidthSize( - final AccountCapsule ownerCapsule, - ChainBaseManager chainBaseManager) { + 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()); TransactionCapsule fakeTransactionCapsule = new TransactionCapsule(builder.build() , ContractType.DelegateResourceContract); diff --git a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java index 001282a0de8..c797c113c77 100644 --- a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java +++ b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java @@ -14,7 +14,6 @@ import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.BytesCapsule; -import org.tron.core.config.Parameter; import org.tron.core.config.Parameter.ChainConstant; import org.tron.core.db.TronStoreWithRevoking; import org.tron.core.exception.BadItemException; @@ -208,6 +207,9 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule> private static final byte[] ALLOW_TVM_SHANGHAI = "ALLOW_TVM_SHANGHAI".getBytes(); + private static final byte[] ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE = + "ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE".getBytes(); + @Autowired private DynamicPropertiesStore(@Value("properties") String dbName) { super(dbName); @@ -2192,7 +2194,7 @@ public long getNextMaintenanceTime() { } public long getMaintenanceSkipSlots() { - return Parameter.ChainConstant.MAINTENANCE_SKIP_SLOTS; + return ChainConstant.MAINTENANCE_SKIP_SLOTS; } public void saveNextMaintenanceTime(long nextMaintenanceTime) { @@ -2218,6 +2220,9 @@ public void updateNextMaintenanceTime(long blockTime) { //The unit is trx public void addTotalNetWeight(long amount) { + if (amount == 0) { + return; + } long totalNetWeight = getTotalNetWeight(); totalNetWeight += amount; if (allowNewReward()) { @@ -2228,6 +2233,9 @@ public void addTotalNetWeight(long amount) { //The unit is trx public void addTotalEnergyWeight(long amount) { + if (amount == 0) { + return; + } long totalEnergyWeight = getTotalEnergyWeight(); totalEnergyWeight += amount; if (allowNewReward()) { @@ -2238,6 +2246,9 @@ public void addTotalEnergyWeight(long amount) { //The unit is trx public void addTotalTronPowerWeight(long amount) { + if (amount == 0) { + return; + } long totalWeight = getTotalTronPowerWeight(); totalWeight += amount; if (allowNewReward()) { @@ -2769,6 +2780,22 @@ public long getAllowTvmShangHai() { .orElse(CommonParameter.getInstance().getAllowTvmShangHai()); } + public void saveAllowOptimizeLockDelegateResource(long allowOptimizeLockDelegateResource) { + this.put(DynamicPropertiesStore.ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE, + new BytesCapsule(ByteArray.fromLong(allowOptimizeLockDelegateResource))); + } + + public long getAllowOptimizeLockDelegateResource() { + return Optional.ofNullable(getUnchecked(ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElse(CommonParameter.getInstance().getAllowOptimizeLockDelegateResource()); + } + + public boolean supportAllowOptimizeLockDelegateResource() { + return getAllowOptimizeLockDelegateResource() == 1L && getUnfreezeDelayDays() > 0; + } + private static class DynamicResourceProperties { private static final byte[] ONE_DAY_NET_LIMIT = "ONE_DAY_NET_LIMIT".getBytes(); diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index ef89e01925a..71836c64a40 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -651,6 +651,10 @@ public class CommonParameter { @Setter public long allowTvmShangHai; + @Getter + @Setter + public long allowOptimizeLockDelegateResource; + private static double calcMaxTimeRatio() { //return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1))); return 5.0; diff --git a/common/src/main/java/org/tron/core/config/Parameter.java b/common/src/main/java/org/tron/core/config/Parameter.java index 5a170577b99..822a79896cc 100644 --- a/common/src/main/java/org/tron/core/config/Parameter.java +++ b/common/src/main/java/org/tron/core/config/Parameter.java @@ -74,6 +74,7 @@ public class ChainConstant { public static final int BLOCK_VERSION = 28; public static final long FROZEN_PERIOD = 86_400_000L; public static final long DELEGATE_PERIOD = 3 * 86_400_000L; + public static final long MAX_BLOCK_NUM_DELEGATE_PERIOD = 10512000L; public static final long TRX_PRECISION = 1000_000L; public static final long DELEGATE_COST_BASE_SIZE = 275L; } diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index a836b15d59d..c5989e19266 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -1325,6 +1325,11 @@ public Protocol.ChainParameters getChainParameters() { .setValue(dbManager.getDynamicPropertiesStore().getAllowTvmShangHai()) .build()); + builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder() + .setKey("getAllowOptimizeLockDelegateResource") + .setValue(dbManager.getDynamicPropertiesStore().getAllowOptimizeLockDelegateResource()) + .build()); + return builder.build(); } diff --git a/framework/src/main/java/org/tron/core/consensus/ProposalService.java b/framework/src/main/java/org/tron/core/consensus/ProposalService.java index 4ca90eae640..f376de4917c 100644 --- a/framework/src/main/java/org/tron/core/consensus/ProposalService.java +++ b/framework/src/main/java/org/tron/core/consensus/ProposalService.java @@ -343,6 +343,13 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule) manager.getDynamicPropertiesStore().saveAllowTvmShangHai(entry.getValue()); break; } + case ALLOW_OPTIMIZE_LOCK_DELEGATE_RESOURCE: { + if (manager.getDynamicPropertiesStore().getAllowOptimizeLockDelegateResource() == 0) { + manager.getDynamicPropertiesStore() + .saveAllowOptimizeLockDelegateResource(entry.getValue()); + } + break; + } default: find = false; break; diff --git a/framework/src/main/java/org/tron/core/services/http/DelegateResourceServlet.java b/framework/src/main/java/org/tron/core/services/http/DelegateResourceServlet.java index 221cc34cf7c..00994238988 100644 --- a/framework/src/main/java/org/tron/core/services/http/DelegateResourceServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/DelegateResourceServlet.java @@ -1,5 +1,6 @@ package org.tron.core.services.http; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -18,6 +19,7 @@ public class DelegateResourceServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { try { PostParams params = PostParams.getPostParams(request); @@ -26,7 +28,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) Transaction tx = wallet .createTransactionCapsule(build.build(), ContractType.DelegateResourceContract) .getInstance(); - JSONObject jsonObject = JSONObject.parseObject(params.getParams()); + JSONObject jsonObject = JSON.parseObject(params.getParams()); tx = Util.setTransactionPermissionId(jsonObject, tx); response.getWriter().println(Util.printCreateTransaction(tx, params.isVisible())); } catch (Exception e) { diff --git a/framework/src/test/java/org/tron/core/WalletTest.java b/framework/src/test/java/org/tron/core/WalletTest.java index 88fa7b6f8f9..b487a0f8421 100644 --- a/framework/src/test/java/org/tron/core/WalletTest.java +++ b/framework/src/test/java/org/tron/core/WalletTest.java @@ -363,6 +363,7 @@ public void testGetEcKey() { public void ss() { for (int i = 0; i < 4; i++) { ECKey ecKey = new ECKey(Utils.getRandom()); + assertNotNull(ecKey); System.out.println(i + 1); System.out.println("privateKey:" + ByteArray.toHexString(ecKey.getPrivKeyBytes())); System.out.println("publicKey:" + ByteArray.toHexString(ecKey.getPubKey())); @@ -483,14 +484,14 @@ public void getPaginatedAssetIssueList() { AssetIssueList assetList1 = wallet.getAssetIssueList(0, 100); assertEquals("get Asset1", assetList1.getAssetIssue(0).getName(), Asset1.getName()); try { - assetList1.getAssetIssue(1); + assertNotNull(assetList1.getAssetIssue(1)); } catch (Exception e) { Assert.assertTrue("AssetIssueList1 size should be 1", true); } AssetIssueList assetList2 = wallet.getAssetIssueList(0, 0); try { - assetList2.getAssetIssue(0); + assertNotNull(assetList2.getAssetIssue(0)); } catch (Exception e) { Assert.assertTrue("AssetIssueList2 size should be 0", true); } @@ -615,12 +616,8 @@ public void testGetDelegatedResource() { delegatedResourceList.getDelegatedResource(0).getFrozenBalanceForBandwidth()); Assert.assertEquals(0L, delegatedResourceList.getDelegatedResource(0).getExpireTimeForBandwidth()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); } catch (Exception e) { - Assert.assertEquals(false, true); + Assert.fail(); } } @@ -794,7 +791,7 @@ public void testGetCanDelegatedMaxSizeBandWidth() { GrpcAPI.CanDelegatedMaxSizeResponseMessage message = wallet.getCanDelegatedMaxSize( ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), BANDWIDTH.getNumber()); - Assert.assertEquals(initBalance - 280L, message.getMaxSize()); + Assert.assertEquals(initBalance - 285L, message.getMaxSize()); } @@ -1054,13 +1051,13 @@ public void testEstimateEnergyOutOfTime() { @Test public void testListNodes() { try { - GrpcAPI.NodeList nodeList = wallet.listNodes(); + wallet.listNodes(); } catch (Exception e) { Assert.assertTrue(e instanceof NullPointerException); } Args.getInstance().setP2pDisable(true); GrpcAPI.NodeList nodeList = wallet.listNodes(); - Assert.assertTrue(nodeList.getNodesList().size() == 0); + assertEquals(0, nodeList.getNodesList().size()); } } diff --git a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java index afbe6895bb9..a232729d3de 100644 --- a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java @@ -1,6 +1,13 @@ package org.tron.core.actuator; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; +import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH; +import static org.tron.protos.contract.Common.ResourceCode.ENERGY; +import static org.tron.protos.contract.Common.ResourceCode.TRON_POWER; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -23,8 +30,8 @@ import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction.Result.code; import org.tron.protos.contract.AssetIssueContractOuterClass; +import org.tron.protos.contract.BalanceContract; import org.tron.protos.contract.BalanceContract.DelegateResourceContract; -import org.tron.protos.contract.Common.ResourceCode; @Slf4j public class DelegateResourceActuatorTest extends BaseTest { @@ -108,18 +115,40 @@ private Any getLockedDelegateContractForBandwidth(String ownerAddress, String re .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(ownerAddress))) .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(receiveAddress))) .setBalance(unfreezeBalance) - .setResource(ResourceCode.BANDWIDTH) + .setResource(BANDWIDTH) .setLock(lock) .build()); } + private Any getOptimizeLockedDelegateContractForBandwidth(long unfreezeBalance, long lockPeriod) { + return Any.pack(DelegateResourceContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))) + .setBalance(unfreezeBalance) + .setResource(BANDWIDTH) + .setLock(true) + .setLockPeriod(lockPeriod) + .build()); + } + + private Any getOptimizeLockedDelegateContractForEnergy(long unfreezeBalance, long lockPeriod) { + return Any.pack(DelegateResourceContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))) + .setBalance(unfreezeBalance) + .setResource(ENERGY) + .setLock(true) + .setLockPeriod(lockPeriod) + .build()); + } + private Any getDelegateContractForCpu(long unfreezeBalance) { return Any.pack( DelegateResourceContract.newBuilder() .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))) .setBalance(unfreezeBalance) - .setResource(ResourceCode.ENERGY) + .setResource(ENERGY) .build()); } @@ -129,7 +158,7 @@ private Any getDelegateContractForTronPower(long unfreezeBalance) { .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))) .setBalance(unfreezeBalance) - .setResource(ResourceCode.TRON_POWER) + .setResource(TRON_POWER) .build()); } @@ -147,12 +176,12 @@ public void testDelegateResourceWithNoFreeze() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", + assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(); + fail(); } actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny( @@ -160,13 +189,13 @@ public void testDelegateResourceWithNoFreeze() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals( + assertEquals( "delegateBalance must be less than available FreezeEnergyV2 balance", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -190,16 +219,15 @@ public void testDelegateBandwidthWithUsage() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", + assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } - @Test public void testDelegateCpuWithUsage() { freezeCpuForOwner(); @@ -220,13 +248,13 @@ public void testDelegateCpuWithUsage() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals( + assertEquals( "delegateBalance must be less than available FreezeEnergyV2 balance", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -252,9 +280,9 @@ public void testDelegateResourceWithContractAddress() { actuator.validate(); actuator.execute(ret); } catch (ContractValidateException e) { - Assert.assertEquals("Do not allow delegate resources to contract addresses", e.getMessage()); + assertEquals("Do not allow delegate resources to contract addresses", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -271,9 +299,9 @@ public void testDelegateResourceToSelf() { actuator.validate(); actuator.execute(ret); } catch (ContractValidateException e) { - Assert.assertEquals("receiverAddress must not be the same as ownerAddress", e.getMessage()); + assertEquals("receiverAddress must not be the same as ownerAddress", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -292,48 +320,48 @@ public void testDelegateResourceForBandwidth() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); + assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerCapsule = dbManager.getAccountStore().get(owner); - Assert.assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); - Assert.assertEquals(initBalance - delegateBalance, + assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); + assertEquals(initBalance - delegateBalance, ownerCapsule.getFrozenV2BalanceForBandwidth()); - Assert.assertEquals(initBalance, ownerCapsule.getTronPower()); + assertEquals(initBalance, ownerCapsule.getTronPower()); AccountCapsule receiverCapsule = dbManager.getAccountStore().get(receiver); - Assert.assertEquals(delegateBalance, + assertEquals(delegateBalance, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth()); - Assert.assertEquals(0L, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy()); - Assert.assertEquals(0L, receiverCapsule.getTronPower()); + assertEquals(0L, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy()); + assertEquals(0L, receiverCapsule.getTronPower()); DelegatedResourceCapsule delegatedResourceCapsule = dbManager.getDelegatedResourceStore() .get(DelegatedResourceCapsule .createDbKeyV2(ByteArray.fromHexString(OWNER_ADDRESS), ByteArray.fromHexString(RECEIVER_ADDRESS), false)); - Assert.assertEquals(delegateBalance, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); + assertEquals(delegateBalance, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); - Assert.assertEquals(totalNetWeightBefore, totalNetWeightAfter); + assertEquals(totalNetWeightBefore, totalNetWeightAfter); //check DelegatedResourceAccountIndex DelegatedResourceAccountIndexCapsule ownerIndexCapsule = dbManager .getDelegatedResourceAccountIndexStore().getV2Index(owner); - Assert.assertEquals(0, ownerIndexCapsule.getFromAccountsList().size()); - Assert.assertEquals(1, ownerIndexCapsule.getToAccountsList().size()); - Assert.assertTrue(ownerIndexCapsule.getToAccountsList() + assertEquals(0, ownerIndexCapsule.getFromAccountsList().size()); + assertEquals(1, ownerIndexCapsule.getToAccountsList().size()); + assertTrue(ownerIndexCapsule.getToAccountsList() .contains(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)))); DelegatedResourceAccountIndexCapsule receiveCapsule = dbManager .getDelegatedResourceAccountIndexStore().getV2Index(receiver); - Assert.assertEquals(0, receiveCapsule.getToAccountsList().size()); - Assert.assertEquals(1, receiveCapsule.getFromAccountsList().size()); - Assert.assertTrue(receiveCapsule.getFromAccountsList() + assertEquals(0, receiveCapsule.getToAccountsList().size()); + assertEquals(1, receiveCapsule.getFromAccountsList().size()); + assertTrue(receiveCapsule.getFromAccountsList() .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); } catch (ContractValidateException | ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -353,22 +381,23 @@ public void testLockedDelegateResourceForBandwidth() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); + assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerCapsule = dbManager.getAccountStore().get(owner); - Assert.assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); - Assert.assertEquals(initBalance - delegateBalance, + assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); + assertEquals(initBalance - delegateBalance, ownerCapsule.getFrozenV2BalanceForBandwidth()); - Assert.assertEquals(initBalance, ownerCapsule.getTronPower()); + assertEquals(initBalance, ownerCapsule.getTronPower()); AccountCapsule receiverCapsule = dbManager.getAccountStore().get(receiver); - Assert.assertEquals(delegateBalance, + assertEquals(delegateBalance, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth()); - Assert.assertEquals(0L, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy()); - Assert.assertEquals(0L, receiverCapsule.getTronPower()); + assertEquals(0L, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy()); + assertEquals(0L, receiverCapsule.getTronPower()); + //check DelegatedResource DelegatedResourceCapsule delegatedResourceCapsule = dbManager.getDelegatedResourceStore() .get(DelegatedResourceCapsule .createDbKeyV2(ByteArray.fromHexString(OWNER_ADDRESS), @@ -380,30 +409,181 @@ public void testLockedDelegateResourceForBandwidth() { Assert.assertNull(delegatedResourceCapsule); Assert.assertNotNull(lockedResourceCapsule); Assert.assertNotEquals(0, lockedResourceCapsule.getExpireTimeForBandwidth()); - Assert.assertEquals(delegateBalance, lockedResourceCapsule.getFrozenBalanceForBandwidth()); + assertEquals(delegateBalance, lockedResourceCapsule.getFrozenBalanceForBandwidth()); long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); - Assert.assertEquals(totalNetWeightBefore, totalNetWeightAfter); + assertEquals(totalNetWeightBefore, totalNetWeightAfter); //check DelegatedResourceAccountIndex DelegatedResourceAccountIndexCapsule ownerIndexCapsule = dbManager .getDelegatedResourceAccountIndexStore().getV2Index(owner); - Assert.assertEquals(0, ownerIndexCapsule.getFromAccountsList().size()); - Assert.assertEquals(1, ownerIndexCapsule.getToAccountsList().size()); - Assert.assertTrue(ownerIndexCapsule.getToAccountsList() + assertEquals(0, ownerIndexCapsule.getFromAccountsList().size()); + assertEquals(1, ownerIndexCapsule.getToAccountsList().size()); + assertTrue(ownerIndexCapsule.getToAccountsList() .contains(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)))); DelegatedResourceAccountIndexCapsule receiveCapsule = dbManager .getDelegatedResourceAccountIndexStore().getV2Index(receiver); - Assert.assertEquals(0, receiveCapsule.getToAccountsList().size()); - Assert.assertEquals(1, receiveCapsule.getFromAccountsList().size()); - Assert.assertTrue(receiveCapsule.getFromAccountsList() + assertEquals(0, receiveCapsule.getToAccountsList().size()); + assertEquals(1, receiveCapsule.getFromAccountsList().size()); + assertTrue(receiveCapsule.getFromAccountsList() .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); } catch (ContractValidateException | ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } + @Test + public void testOptimizeLockedDelegateResourceForBandwidthWrongLockPeriod1() { + dbManager.getDynamicPropertiesStore().saveAllowOptimizeLockDelegateResource(1); + freezeBandwidthForOwner(); + long delegateBalance = 1_000_000_000L; + DelegateResourceActuator actuator = new DelegateResourceActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForBandwidth( + delegateBalance, 370 * 24 * 3600)); + assertThrows("The lock period of delegate resources cannot exceed 1 year!", + ContractValidateException.class, actuator::validate); + } + + @Test + public void testOptimizeLockedDelegateResourceForBandwidthWrongLockPeriod2() { + dbManager.getDynamicPropertiesStore().saveAllowOptimizeLockDelegateResource(1); + freezeBandwidthForOwner(); + long delegateBalance = 1_000_000_000L; + DelegateResourceActuator actuator = new DelegateResourceActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForBandwidth( + delegateBalance, 60)); + + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + assertEquals(code.SUCESS, ret.getInstance().getRet()); + } catch (ContractValidateException | ContractExeException e) { + fail(e.getMessage()); + } + + DelegateResourceActuator actuator1 = new DelegateResourceActuator(); + actuator1.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForBandwidth( + delegateBalance, 30)); + assertThrows("The lock period for bandwidth this time cannot be less than the remaining" + + " time[60000s] of the last lock period for bandwidth!", + ContractValidateException.class, actuator1::validate); + } + + @Test + public void testOptimizeLockedDelegateResourceForBandwidth() { + dbManager.getDynamicPropertiesStore().saveAllowOptimizeLockDelegateResource(1); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(50_000L); + freezeBandwidthForOwner(); + long delegateBalance = 1_000_000_000L; + DelegateResourceActuator actuator = new DelegateResourceActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForBandwidth( + delegateBalance, 60)); + + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + assertEquals(code.SUCESS, ret.getInstance().getRet()); + } catch (ContractValidateException | ContractExeException e) { + fail(e.getMessage()); + } + + DelegateResourceActuator actuator1 = new DelegateResourceActuator(); + actuator1.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForBandwidth( + delegateBalance, 60)); + + TransactionResultCapsule ret1 = new TransactionResultCapsule(); + try { + actuator1.validate(); + actuator1.execute(ret1); + assertEquals(code.SUCESS, ret1.getInstance().getRet()); + } catch (ContractValidateException | ContractExeException e) { + fail(e.getMessage()); + } + DelegatedResourceCapsule lockedResourceCapsule = dbManager.getDelegatedResourceStore() + .get(DelegatedResourceCapsule + .createDbKeyV2(ByteArray.fromHexString(OWNER_ADDRESS), + ByteArray.fromHexString(RECEIVER_ADDRESS), true)); + long expireTimeForBandwidth = lockedResourceCapsule.getExpireTimeForBandwidth(); + assertEquals(50_000L + 60 * 3 * 1000, expireTimeForBandwidth); + assertTrue(expireTimeForBandwidth > 60_000); + } + + @Test + public void testOptimizeLockedDelegateResourceForEnergy() { + dbManager.getDynamicPropertiesStore().saveAllowOptimizeLockDelegateResource(1); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(50_000L); + freezeCpuForOwner(); + long delegateBalance = 1_000_000_000L; + DelegateResourceActuator actuator = new DelegateResourceActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForEnergy( + delegateBalance, 60)); + + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + assertEquals(code.SUCESS, ret.getInstance().getRet()); + } catch (ContractValidateException | ContractExeException e) { + fail(e.getMessage()); + } + + DelegateResourceActuator actuator1 = new DelegateResourceActuator(); + actuator1.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForEnergy( + delegateBalance, 60)); + + TransactionResultCapsule ret1 = new TransactionResultCapsule(); + try { + actuator1.validate(); + actuator1.execute(ret1); + assertEquals(code.SUCESS, ret1.getInstance().getRet()); + } catch (ContractValidateException | ContractExeException e) { + fail(e.getMessage()); + } + DelegatedResourceCapsule lockedResourceCapsule = dbManager.getDelegatedResourceStore() + .get(DelegatedResourceCapsule + .createDbKeyV2(ByteArray.fromHexString(OWNER_ADDRESS), + ByteArray.fromHexString(RECEIVER_ADDRESS), true)); + assertTrue(lockedResourceCapsule.getExpireTimeForEnergy() > 60_000); + } + + @Test + public void testOptimizeLockedDelegateResourceForEnergyWrongLockPeriod2() { + dbManager.getDynamicPropertiesStore().saveAllowOptimizeLockDelegateResource(1); + freezeCpuForOwner(); + long delegateBalance = 1_000_000_000L; + DelegateResourceActuator actuator = new DelegateResourceActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForEnergy( + delegateBalance, 60)); + + TransactionResultCapsule ret = new TransactionResultCapsule(); + try { + actuator.validate(); + actuator.execute(ret); + assertEquals(code.SUCESS, ret.getInstance().getRet()); + } catch (ContractValidateException | ContractExeException e) { + fail(e.getMessage()); + } + + DelegateResourceActuator actuator1 = new DelegateResourceActuator(); + actuator1.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getOptimizeLockedDelegateContractForEnergy( + delegateBalance, 30)); + assertThrows("The lock period for energy this time cannot be less than the remaining" + + " time[60000s] of the last lock period for energy!", + ContractValidateException.class, actuator1::validate); + } + @Test public void testDelegateResourceForCpu() { freezeCpuForOwner(); @@ -419,53 +599,50 @@ public void testDelegateResourceForCpu() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); + assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerCapsule = dbManager.getAccountStore().get(owner); - Assert.assertEquals(initBalance, ownerCapsule.getBalance()); - Assert.assertEquals(0L, ownerCapsule.getFrozenBalance()); - Assert.assertEquals(0L, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); - Assert.assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForEnergy()); - Assert.assertEquals(initBalance, ownerCapsule.getTronPower()); + assertEquals(initBalance, ownerCapsule.getBalance()); + assertEquals(0L, ownerCapsule.getFrozenBalance()); + assertEquals(0L, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); + assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForEnergy()); + assertEquals(initBalance, ownerCapsule.getTronPower()); AccountCapsule receiverCapsule = dbManager.getAccountStore().get(receiver); - Assert.assertEquals(0L, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth()); - Assert.assertEquals(delegateBalance, + assertEquals(0L, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth()); + assertEquals(delegateBalance, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy()); - Assert.assertEquals(0L, receiverCapsule.getTronPower()); + assertEquals(0L, receiverCapsule.getTronPower()); DelegatedResourceCapsule delegatedResourceCapsule = dbManager.getDelegatedResourceStore() .get(DelegatedResourceCapsule.createDbKeyV2(owner, receiver, false)); - Assert.assertEquals(0L, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); - Assert.assertEquals(delegateBalance, delegatedResourceCapsule.getFrozenBalanceForEnergy()); + assertEquals(0L, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); + assertEquals(delegateBalance, delegatedResourceCapsule.getFrozenBalanceForEnergy()); long totalEnergyWeightAfter = dbManager.getDynamicPropertiesStore().getTotalEnergyWeight(); - Assert.assertEquals(totalEnergyWeightBefore, totalEnergyWeightAfter); + assertEquals(totalEnergyWeightBefore, totalEnergyWeightAfter); //check DelegatedResourceAccountIndex DelegatedResourceAccountIndexCapsule ownerIndexCapsule = dbManager .getDelegatedResourceAccountIndexStore().getV2Index(owner); - Assert - .assertEquals(0, ownerIndexCapsule.getFromAccountsList().size()); - Assert.assertEquals(1, ownerIndexCapsule.getToAccountsList().size()); - Assert.assertTrue(ownerIndexCapsule.getToAccountsList() + assertEquals(0, ownerIndexCapsule.getFromAccountsList().size()); + assertEquals(1, ownerIndexCapsule.getToAccountsList().size()); + assertTrue(ownerIndexCapsule.getToAccountsList() .contains(ByteString.copyFrom(receiver))); DelegatedResourceAccountIndexCapsule receiverIndexCapsule = dbManager .getDelegatedResourceAccountIndexStore().getV2Index(receiver); - Assert - .assertEquals(0, receiverIndexCapsule.getToAccountsList().size()); - Assert - .assertEquals(1, + assertEquals(0, receiverIndexCapsule.getToAccountsList().size()); + assertEquals(1, receiverIndexCapsule.getFromAccountsList().size()); - Assert.assertTrue(receiverIndexCapsule.getFromAccountsList() + assertTrue(receiverIndexCapsule.getFromAccountsList() .contains(ByteString.copyFrom(owner))); } catch (ContractValidateException | ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -480,11 +657,11 @@ public void delegateLessThanZero() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals("delegateBalance must be more than 1TRX", e.getMessage()); + assertEquals("delegateBalance must be more than 1TRX", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -498,12 +675,12 @@ public void delegateTronPower() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals("ResourceCode error, valid ResourceCode[BANDWIDTH、ENERGY]", + assertEquals("ResourceCode error, valid ResourceCode[BANDWIDTH、ENERGY]", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -518,12 +695,12 @@ public void delegateMoreThanBalance() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", + assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -538,15 +715,25 @@ public void invalidOwnerAddress() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals("Invalid address", e.getMessage()); + assertEquals("Invalid address", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } + @Test + public void invalidReceiverAddress() { + freezeBandwidthForOwner(); + DelegateResourceActuator actuator = new DelegateResourceActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()) + .setAny(getDelegateContractForBandwidth( + OWNER_ADDRESS, OWNER_ADDRESS_INVALID, 1_000_000_000L)); + assertThrows("Invalid receiverAddress", ContractValidateException.class, actuator::validate); + } + @Test public void invalidOwnerAccount() { DelegateResourceActuator actuator = new DelegateResourceActuator(); @@ -558,12 +745,12 @@ public void invalidOwnerAccount() { try { actuator.validate(); actuator.execute(ret); - Assert.fail("cannot run here."); + fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertEquals("Account[" + OWNER_ACCOUNT_INVALID + "] not exists", + assertEquals("Account[" + OWNER_ACCOUNT_INVALID + "] not exists", e.getMessage()); } catch (ContractExeException e) { - Assert.fail(e.getMessage()); + fail(e.getMessage()); } } @@ -588,4 +775,20 @@ public void commonErrorCheck() { actuatorTest.setNullDBManagerMsg("No account store or dynamic store!"); actuatorTest.nullDBManger(); } + + @Test + public void testErrorContract() { + DelegateResourceActuator actuator = new DelegateResourceActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny(getErrorContract()); + assertThrows( + "contract type error, expected type [DelegateResourceContract], " + + "real type[WithdrawExpireUnfreezeContract]", + ContractValidateException.class, actuator::validate); + } + + private Any getErrorContract() { + return Any.pack(BalanceContract.WithdrawExpireUnfreezeContract.newBuilder().setOwnerAddress( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))).build() + ); + } } diff --git a/framework/src/test/java/org/tron/core/actuator/utils/TransactionUtilTest.java b/framework/src/test/java/org/tron/core/actuator/utils/TransactionUtilTest.java index ad8846743e5..6bee877318a 100644 --- a/framework/src/test/java/org/tron/core/actuator/utils/TransactionUtilTest.java +++ b/framework/src/test/java/org/tron/core/actuator/utils/TransactionUtilTest.java @@ -1,22 +1,35 @@ package org.tron.core.actuator.utils; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.tron.core.capsule.utils.TransactionUtil.isNumber; +import static org.tron.core.utils.TransactionUtil.validAccountId; +import static org.tron.core.utils.TransactionUtil.validAccountName; +import static org.tron.core.utils.TransactionUtil.validAssetName; +import static org.tron.core.utils.TransactionUtil.validTokenAbbrName; +import com.google.protobuf.ByteString; import java.nio.charset.StandardCharsets; import lombok.extern.slf4j.Slf4j; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; import org.tron.core.config.args.Args; import org.tron.core.utils.TransactionUtil; +import org.tron.protos.Protocol.AccountType; @Slf4j(topic = "capsule") public class TransactionUtilTest extends BaseTest { + private static String OWNER_ADDRESS; + /** * Init . */ @@ -24,81 +37,96 @@ public class TransactionUtilTest extends BaseTest { public static void init() { dbPath = "output_transactionUtil_test"; Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + + } + + @Before + public void setUp() { + byte[] owner = ByteArray.fromHexString(OWNER_ADDRESS); + AccountCapsule ownerCapsule = + new AccountCapsule( + ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(owner), + AccountType.Normal, + 10_000_000_000L); + ownerCapsule.setFrozenForBandwidth(1000000L, 1000000L); + dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); } @Test public void validAccountNameCheck() { - String account = ""; - assertTrue(TransactionUtil.validAccountName(account.getBytes(StandardCharsets.UTF_8))); + StringBuilder account = new StringBuilder(); + assertTrue(validAccountName(account.toString().getBytes(StandardCharsets.UTF_8))); for (int i = 0; i < 200; i++) { - account += (char) ('a' + (i % 26)); + account.append((char) ('a' + (i % 26))); } - assertTrue(TransactionUtil.validAccountName(account.getBytes(StandardCharsets.UTF_8))); - account += 'z'; - assertFalse(TransactionUtil.validAccountName(account.getBytes(StandardCharsets.UTF_8))); + assertTrue(validAccountName(account.toString().getBytes(StandardCharsets.UTF_8))); + account.append('z'); + assertFalse(validAccountName(account.toString().getBytes(StandardCharsets.UTF_8))); } @Test public void validAccountIdCheck() { - String accountId = ""; - assertFalse(TransactionUtil.validAccountId(accountId.getBytes(StandardCharsets.UTF_8))); + StringBuilder accountId = new StringBuilder(); + assertFalse(validAccountId(accountId.toString().getBytes(StandardCharsets.UTF_8))); for (int i = 0; i < 7; i++) { - accountId += (char) ('a' + (i % 26)); + accountId.append((char) ('a' + (i % 26))); } - assertFalse(TransactionUtil.validAccountId(accountId.getBytes(StandardCharsets.UTF_8))); + assertFalse(validAccountId(accountId.toString().getBytes(StandardCharsets.UTF_8))); for (int i = 0; i < 26; i++) { - accountId += (char) ('a' + (i % 26)); + accountId.append((char) ('a' + (i % 26))); } - assertFalse(TransactionUtil.validAccountId(accountId.getBytes(StandardCharsets.UTF_8))); - accountId = "ab cdefghij"; - assertFalse(TransactionUtil.validAccountId(accountId.getBytes(StandardCharsets.UTF_8))); - accountId = (char) 128 + "abcdefjijk" + (char) 129; - assertFalse(TransactionUtil.validAccountId(accountId.getBytes(StandardCharsets.UTF_8))); - accountId = ""; + assertFalse(validAccountId(accountId.toString().getBytes(StandardCharsets.UTF_8))); + accountId = new StringBuilder("ab cdefghij"); + assertFalse(validAccountId(accountId.toString().getBytes(StandardCharsets.UTF_8))); + accountId = new StringBuilder((char) 128 + "abcdefjijk" + (char) 129); + assertFalse(validAccountId(accountId.toString().getBytes(StandardCharsets.UTF_8))); + accountId = new StringBuilder(); for (int i = 0; i < 30; i++) { - accountId += (char) ('a' + (i % 26)); + accountId.append((char) ('a' + (i % 26))); } - assertTrue(TransactionUtil.validAccountId(accountId.getBytes(StandardCharsets.UTF_8))); + assertTrue(validAccountId(accountId.toString().getBytes(StandardCharsets.UTF_8))); } @Test public void validAssetNameCheck() { - String assetName = ""; - assertFalse(TransactionUtil.validAssetName(assetName.getBytes(StandardCharsets.UTF_8))); + StringBuilder assetName = new StringBuilder(); + assertFalse(validAssetName(assetName.toString().getBytes(StandardCharsets.UTF_8))); for (int i = 0; i < 33; i++) { - assetName += (char) ('a' + (i % 26)); + assetName.append((char) ('a' + (i % 26))); } - assertFalse(TransactionUtil.validAssetName(assetName.getBytes(StandardCharsets.UTF_8))); - assetName = "ab cdefghij"; - assertFalse(TransactionUtil.validAssetName(assetName.getBytes(StandardCharsets.UTF_8))); - assetName = (char) 128 + "abcdefjijk" + (char) 129; - assertFalse(TransactionUtil.validAssetName(assetName.getBytes(StandardCharsets.UTF_8))); - assetName = ""; + assertFalse(validAssetName(assetName.toString().getBytes(StandardCharsets.UTF_8))); + assetName = new StringBuilder("ab cdefghij"); + assertFalse(validAssetName(assetName.toString().getBytes(StandardCharsets.UTF_8))); + assetName = new StringBuilder((char) 128 + "abcdefjijk" + (char) 129); + assertFalse(validAssetName(assetName.toString().getBytes(StandardCharsets.UTF_8))); + assetName = new StringBuilder(); for (int i = 0; i < 20; i++) { - assetName += (char) ('a' + (i % 26)); + assetName.append((char) ('a' + (i % 26))); } - assertTrue(TransactionUtil.validAssetName(assetName.getBytes(StandardCharsets.UTF_8))); + assertTrue(validAssetName(assetName.toString().getBytes(StandardCharsets.UTF_8))); } @Test public void validTokenAbbrNameCheck() { - String abbrName = ""; - assertFalse(TransactionUtil.validTokenAbbrName(abbrName.getBytes(StandardCharsets.UTF_8))); + StringBuilder abbrName = new StringBuilder(); + assertFalse(validTokenAbbrName(abbrName.toString().getBytes(StandardCharsets.UTF_8))); for (int i = 0; i < 6; i++) { - abbrName += (char) ('a' + (i % 26)); + abbrName.append((char) ('a' + (i % 26))); } - assertFalse(TransactionUtil.validTokenAbbrName(abbrName.getBytes(StandardCharsets.UTF_8))); - abbrName = "a bd"; - assertFalse(TransactionUtil.validTokenAbbrName(abbrName.getBytes(StandardCharsets.UTF_8))); - abbrName = "a" + (char) 129 + 'f'; - assertFalse(TransactionUtil.validTokenAbbrName(abbrName.getBytes(StandardCharsets.UTF_8))); - abbrName = ""; + assertFalse(validTokenAbbrName(abbrName.toString().getBytes(StandardCharsets.UTF_8))); + abbrName = new StringBuilder("a bd"); + assertFalse(validTokenAbbrName(abbrName.toString().getBytes(StandardCharsets.UTF_8))); + abbrName = new StringBuilder("a" + (char) 129 + 'f'); + assertFalse(validTokenAbbrName(abbrName.toString().getBytes(StandardCharsets.UTF_8))); + abbrName = new StringBuilder(); for (int i = 0; i < 5; i++) { - abbrName += (char) ('a' + (i % 26)); + abbrName.append((char) ('a' + (i % 26))); } - assertTrue(TransactionUtil.validTokenAbbrName(abbrName.getBytes(StandardCharsets.UTF_8))); + assertTrue(validTokenAbbrName(abbrName.toString().getBytes(StandardCharsets.UTF_8))); } @Test @@ -114,4 +142,13 @@ public void isNumberCheck() { assertTrue(isNumber(number.getBytes(StandardCharsets.UTF_8))); } + @Test + public void testEstimateConsumeBandWidthSize() { + AccountCapsule ownerCapsule = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + long estimateConsumeBandWidthSize = TransactionUtil.estimateConsumeBandWidthSize(ownerCapsule, + dbManager.getChainBaseManager()); + assertEquals(278L, estimateConsumeBandWidthSize); + } + } diff --git a/protocol/src/main/protos/core/contract/balance_contract.proto b/protocol/src/main/protos/core/contract/balance_contract.proto index 90a2dfaa48d..9c0bded1cbc 100644 --- a/protocol/src/main/protos/core/contract/balance_contract.proto +++ b/protocol/src/main/protos/core/contract/balance_contract.proto @@ -103,6 +103,7 @@ message DelegateResourceContract { int64 balance = 3; bytes receiver_address = 4; bool lock = 5; + int64 lock_period = 6; } message UnDelegateResourceContract {