Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(freezeV2): optimize delegate resource lock period #5255

Merged
merged 12 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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["
Expand All @@ -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");
}
Expand Down Expand Up @@ -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");
Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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),
Expand Down
19 changes: 18 additions & 1 deletion actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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()) {
Expand All @@ -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()) {
Expand All @@ -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()) {
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions common/src/main/java/org/tron/core/config/Parameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions framework/src/main/java/org/tron/core/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
Expand All @@ -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) {
Expand Down
Loading