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(proposal,tvm): implement TIP-653 #5837

Merged
8 changes: 8 additions & 0 deletions actuator/src/main/java/org/tron/core/actuator/VMActuator.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.tron.core.utils.TransactionUtil;
import org.tron.core.vm.EnergyCost;
import org.tron.core.vm.LogInfoTriggerParser;
import org.tron.core.vm.Op;
import org.tron.core.vm.OperationRegistry;
import org.tron.core.vm.VM;
import org.tron.core.vm.VMConstant;
Expand Down Expand Up @@ -189,6 +190,13 @@ public void execute(Object object) throws ContractExeException {
VM.play(program, OperationRegistry.getTable());
result = program.getResult();

if (VMConfig.allowEnergyAdjustment()) {
// If the last op consumed too much execution time, the CPU time limit for the whole tx can be exceeded.
// This is not fair for other txs in the same block.
// So when allowFairEnergyAdjustment is on, the CPU time limit will be checked at the end of tx execution.
program.checkCPUTimeLimit(Op.getNameOf(program.getLastOp()) + "(TX_LAST_OP)");
}

if (TrxType.TRX_CONTRACT_CREATION_TYPE == trxType && !result.isRevert()) {
byte[] code = program.getResult().getHReturn();
if (code.length != 0 && VMConfig.allowTvmLondon() && code[0] == (byte) 0xEF) {
Expand Down
16 changes: 16 additions & 0 deletions actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,21 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
}
break;
}
case ALLOW_ENERGY_ADJUSTMENT: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_5)) {
throw new ContractValidateException(
"Bad chain parameter id [ALLOW_ENERGY_ADJUSTMENT]");
}
if (dynamicPropertiesStore.getAllowEnergyAdjustment() == 1) {
throw new ContractValidateException(
"[ALLOW_ENERGY_ADJUSTMENT] has been valid, no need to propose again");
}
if (value != 1) {
throw new ContractValidateException(
"This value[ALLOW_ENERGY_ADJUSTMENT] is only allowed to be 1");
}
break;
}
case MAX_CREATE_ACCOUNT_TX_SIZE: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_5)) {
throw new ContractValidateException(
Expand Down Expand Up @@ -841,6 +856,7 @@ public enum ProposalType { // current value, value range
ALLOW_CANCEL_ALL_UNFREEZE_V2(77), // 0, 1
MAX_DELEGATE_LOCK_PERIOD(78), // (86400, 10512000]
ALLOW_OLD_REWARD_OPT(79), // 0, 1
ALLOW_ENERGY_ADJUSTMENT(81), // 0, 1
MAX_CREATE_ACCOUNT_TX_SIZE(82); // [500, 10000]

private long code;
Expand Down
31 changes: 30 additions & 1 deletion actuator/src/main/java/org/tron/core/vm/EnergyCost.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,19 @@ public static long getSuicideCost(Program ignored) {
return SUICIDE;
}

public static long getSuicideCost2(Program program) {
DataWord inheritorAddress = program.getStack().peek();
if (isDeadAccount(program, inheritorAddress)) {
return getSuicideCost(program) + NEW_ACCT_CALL;
}
return getSuicideCost(program);
}

public static long getBalanceCost(Program ignored) {
return BALANCE;
}

public static long getFreezeCost(Program program) {

Stack stack = program.getStack();
DataWord receiverAddressWord = stack.get(stack.size() - 3);
if (isDeadAccount(program, receiverAddressWord)) {
Expand Down Expand Up @@ -306,7 +313,27 @@ public static long getUnDelegateResourceCost(Program ignored) {
}

public static long getVoteWitnessCost(Program program) {
Stack stack = program.getStack();
long oldMemSize = program.getMemSize();
DataWord amountArrayLength = stack.get(stack.size() - 1).clone();
DataWord amountArrayOffset = stack.get(stack.size() - 2);
DataWord witnessArrayLength = stack.get(stack.size() - 3).clone();
DataWord witnessArrayOffset = stack.get(stack.size() - 4);

DataWord wordSize = new DataWord(DataWord.WORD_SIZE);

amountArrayLength.mul(wordSize);
BigInteger amountArrayMemoryNeeded = memNeeded(amountArrayOffset, amountArrayLength);

witnessArrayLength.mul(wordSize);
BigInteger witnessArrayMemoryNeeded = memNeeded(witnessArrayOffset, witnessArrayLength);

return VOTE_WITNESS + calcMemEnergy(oldMemSize,
(amountArrayMemoryNeeded.compareTo(witnessArrayMemoryNeeded) > 0
? amountArrayMemoryNeeded : witnessArrayMemoryNeeded), 0, Op.VOTEWITNESS);
}

public static long getVoteWitnessCost2(Program program) {
Stack stack = program.getStack();
long oldMemSize = program.getMemSize();
DataWord amountArrayLength = stack.get(stack.size() - 1).clone();
Expand All @@ -317,9 +344,11 @@ public static long getVoteWitnessCost(Program program) {
DataWord wordSize = new DataWord(DataWord.WORD_SIZE);

amountArrayLength.mul(wordSize);
amountArrayLength.add(wordSize); // dynamic array length is at least 32 bytes
BigInteger amountArrayMemoryNeeded = memNeeded(amountArrayOffset, amountArrayLength);

witnessArrayLength.mul(wordSize);
witnessArrayLength.add(wordSize); // dynamic array length is at least 32 bytes
BigInteger witnessArrayMemoryNeeded = memNeeded(witnessArrayOffset, witnessArrayLength);

return VOTE_WITNESS + calcMemEnergy(oldMemSize,
Expand Down
17 changes: 17 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/OperationRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ public static JumpTable getTable() {
adjustMemOperations(table);
}

if (VMConfig.allowEnergyAdjustment()) {
adjustForFairEnergy(table);
}

return table;
}

Expand Down Expand Up @@ -635,4 +639,17 @@ public static void appendShangHaiOperations(JumpTable table) {
OperationActions::push0Action,
proposal));
}

public static void adjustForFairEnergy(JumpTable table) {
table.set(new Operation(
Op.VOTEWITNESS, 4, 1,
EnergyCost::getVoteWitnessCost2,
OperationActions::voteWitnessAction,
VMConfig::allowTvmVote));

table.set(new Operation(
Op.SUICIDE, 1, 0,
EnergyCost::getSuicideCost2,
OperationActions::suicideAction));
}
}
7 changes: 6 additions & 1 deletion actuator/src/main/java/org/tron/core/vm/VMUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import lombok.extern.slf4j.Slf4j;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.ByteUtil;
import org.tron.common.utils.Commons;
import org.tron.common.utils.DecodeUtil;
import org.tron.core.Constant;
import org.tron.core.capsule.AccountCapsule;
import org.tron.core.exception.ContractValidateException;
import org.tron.core.vm.config.VMConfig;
Expand All @@ -33,6 +33,11 @@ public final class VMUtils {
private VMUtils() {
}

public static int getAddressSize() {
return VMConfig.allowEnergyAdjustment() ?
Constant.TRON_ADDRESS_SIZE : Constant.STANDARD_ADDRESS_SIZE;
}

public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public static void load(StoreFactory storeFactory) {
VMConfig.initDynamicEnergyIncreaseFactor(ds.getDynamicEnergyIncreaseFactor());
VMConfig.initDynamicEnergyMaxFactor(ds.getDynamicEnergyMaxFactor());
VMConfig.initAllowTvmShangHai(ds.getAllowTvmShangHai());
VMConfig.initAllowEnergyAdjustment(ds.getAllowEnergyAdjustment());
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/config/VMConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class VMConfig {

private static boolean ALLOW_TVM_SHANGHAI = false;

private static boolean ALLOW_ENERGY_ADJUSTMENT = false;

private VMConfig() {
}

Expand Down Expand Up @@ -136,6 +138,10 @@ public static void initAllowTvmShangHai(long allow) {
ALLOW_TVM_SHANGHAI = allow == 1;
}

public static void initAllowEnergyAdjustment(long allow) {
ALLOW_ENERGY_ADJUSTMENT = allow == 1;
}

public static boolean getEnergyLimitHardFork() {
return CommonParameter.ENERGY_LIMIT_HARD_FORK;
}
Expand Down Expand Up @@ -211,4 +217,8 @@ public static long getDynamicEnergyMaxFactor() {
public static boolean allowTvmShanghai() {
return ALLOW_TVM_SHANGHAI;
}

public static boolean allowEnergyAdjustment() {
return ALLOW_ENERGY_ADJUSTMENT;
}
}
7 changes: 6 additions & 1 deletion actuator/src/main/java/org/tron/core/vm/program/Program.java
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ public void setLastOp(byte op) {
this.lastOp = op;
}

public byte getLastOp() {
return this.lastOp;
}

/**
* Returns the last fully executed OP.
*/
Expand Down Expand Up @@ -457,7 +461,8 @@ public void suicide(DataWord obtainerAddress) {
InternalTransaction internalTx = addInternalTx(null, owner, obtainer, balance, null,
"suicide", nonce, getContractState().getAccount(owner).getAssetMapV2());

if (FastByteComparisons.compareTo(owner, 0, 20, obtainer, 0, 20) == 0) {
int ADDRESS_SIZE = VMUtils.getAddressSize();
if (FastByteComparisons.compareTo(owner, 0, ADDRESS_SIZE, obtainer, 0, ADDRESS_SIZE) == 0) {
// if owner == obtainer just zeroing account according to Yellow Paper
getContractState().addBalance(owner, -balance);
byte[] blackHoleAddress = getContractState().getBlackHoleAddress();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>

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

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

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

@Autowired
Expand Down Expand Up @@ -2852,6 +2854,17 @@ public long getAllowOldRewardOpt() {
.orElse(CommonParameter.getInstance().getAllowOldRewardOpt());
}

public void saveAllowEnergyAdjustment(long allowEnergyAdjustment) {
this.put(ALLOW_ENERGY_ADJUSTMENT, new BytesCapsule(ByteArray.fromLong(allowEnergyAdjustment)));
}

public long getAllowEnergyAdjustment() {
return Optional.ofNullable(getUnchecked(ALLOW_ENERGY_ADJUSTMENT))
.map(BytesCapsule::getData)
.map(ByteArray::toLong)
.orElse(CommonParameter.getInstance().getAllowEnergyAdjustment());
}

public void saveMaxCreateAccountTxSize(long maxCreateAccountTxSize) {
this.put(MAX_CREATE_ACCOUNT_TX_SIZE,
new BytesCapsule(ByteArray.fromLong(maxCreateAccountTxSize)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,10 @@ public class CommonParameter {
@Setter
public long allowOldRewardOpt;

@Getter
@Setter
public long allowEnergyAdjustment;

@Getter
@Setter
public long maxCreateAccountTxSize = 1000L;
Expand Down
4 changes: 4 additions & 0 deletions common/src/main/java/org/tron/core/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class Constant {
public static final String ADD_PRE_FIX_STRING_MAINNET = "41";
public static final byte ADD_PRE_FIX_BYTE_TESTNET = (byte) 0xa0; //a0 + address
public static final String ADD_PRE_FIX_STRING_TESTNET = "a0";
public static final int STANDARD_ADDRESS_SIZE = 20;
public static final int TRON_ADDRESS_SIZE = 21;

public static final int NODE_TYPE_FULL_NODE = 0;
public static final int NODE_TYPE_LIGHT_NODE = 1;
Expand Down Expand Up @@ -379,4 +381,6 @@ public class Constant {

public static final String MAX_UNSOLIDIFIED_BLOCKS = "node.maxUnsolidifiedBlocks";
public static final String COMMITTEE_ALLOW_OLD_REWARD_OPT = "committee.allowOldRewardOpt";

public static final String COMMITTEE_ALLOW_ENERGY_ADJUSTMENT = "committee.allowEnergyAdjustment";
}
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 @@ -1334,6 +1334,11 @@ public Protocol.ChainParameters getChainParameters() {
.setValue(dbManager.getDynamicPropertiesStore().getAllowOldRewardOpt())
.build());

builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder()
.setKey("getAllowEnergyAdjustment")
.setValue(dbManager.getDynamicPropertiesStore().getAllowEnergyAdjustment())
.build());

builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder()
.setKey("getMaxCreateAccountTxSize")
.setValue(dbManager.getDynamicPropertiesStore().getMaxCreateAccountTxSize())
Expand Down
5 changes: 5 additions & 0 deletions framework/src/main/java/org/tron/core/config/args/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ public static void clearParam() {
PARAMETER.unsolidifiedBlockCheck = false;
PARAMETER.maxUnsolidifiedBlocks = 54;
PARAMETER.allowOldRewardOpt = 0;
PARAMETER.allowEnergyAdjustment = 0;
}

/**
Expand Down Expand Up @@ -1205,6 +1206,10 @@ public static void setParam(final String[] args, final String confFileName) {
}
PARAMETER.allowOldRewardOpt = allowOldRewardOpt;

PARAMETER.allowEnergyAdjustment =
config.hasPath(Constant.COMMITTEE_ALLOW_ENERGY_ADJUSTMENT) ? config
.getInt(Constant.COMMITTEE_ALLOW_ENERGY_ADJUSTMENT) : 0;

logConfig();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule)
manager.getDynamicPropertiesStore().saveAllowOldRewardOpt(entry.getValue());
break;
}
case ALLOW_ENERGY_ADJUSTMENT: {
manager.getDynamicPropertiesStore().saveAllowEnergyAdjustment(entry.getValue());
break;
}
case MAX_CREATE_ACCOUNT_TX_SIZE: {
manager.getDynamicPropertiesStore().saveMaxCreateAccountTxSize(entry.getValue());
break;
Expand Down
Loading