Skip to content

Commit d1f8511

Browse files
committed
func(proposal,tvm): add energy adjustment proposal and implement
1 parent 76df76c commit d1f8511

File tree

15 files changed

+123
-6
lines changed

15 files changed

+123
-6
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ public void execute(Object object) throws ContractExeException {
189189
VM.play(program, OperationRegistry.getTable());
190190
result = program.getResult();
191191

192+
if (VMConfig.allowEnergyAdjustment()) {
193+
// If the last op consumed too much execution time, the CPU time limit for the whole tx can be exceeded.
194+
// This is not fair for other txs in the same block.
195+
// So when allowFairEnergyAdjustment is on, the CPU time limit will be checked at the end of tx execution.
196+
program.checkCPUTimeLimit("TX_LAST_OP");
197+
}
198+
192199
if (TrxType.TRX_CONTRACT_CREATION_TYPE == trxType && !result.isRevert()) {
193200
byte[] code = program.getResult().getHReturn();
194201
if (code.length != 0 && VMConfig.allowTvmLondon() && code[0] == (byte) 0xEF) {

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,16 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
748748
}
749749
break;
750750
}
751+
case ALLOW_ENERGY_ADJUSTMENT: {
752+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_5)) {
753+
throw new ContractValidateException(
754+
"Bad chain parameter id [ALLOW_ENERGY_ADJUSTMENT]");
755+
}
756+
if (value != 1) {
757+
throw new ContractValidateException(
758+
"This value[ALLOW_ENERGY_ADJUSTMENT] is only allowed to be 1");
759+
}
760+
}
751761
default:
752762
break;
753763
}
@@ -824,7 +834,8 @@ public enum ProposalType { // current value, value range
824834
ALLOW_TVM_SHANGHAI(76), // 0, 1
825835
ALLOW_CANCEL_ALL_UNFREEZE_V2(77), // 0, 1
826836
MAX_DELEGATE_LOCK_PERIOD(78), // (86400, 10512000]
827-
ALLOW_OLD_REWARD_OPT(79); // 0, 1
837+
ALLOW_OLD_REWARD_OPT(79), // 0, 1
838+
ALLOW_ENERGY_ADJUSTMENT(80); // 0, 1
828839

829840
private long code;
830841

actuator/src/main/java/org/tron/core/vm/EnergyCost.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,19 @@ public static long getSuicideCost(Program ignored) {
259259
return SUICIDE;
260260
}
261261

262+
public static long getSuicideCost2(Program program) {
263+
DataWord inheritorAddress = program.getStack().peek();
264+
if (isDeadAccount(program, inheritorAddress)) {
265+
return getSuicideCost(program) + NEW_ACCT_CALL;
266+
}
267+
return getSuicideCost(program);
268+
}
269+
262270
public static long getBalanceCost(Program ignored) {
263271
return BALANCE;
264272
}
265273

266274
public static long getFreezeCost(Program program) {
267-
268275
Stack stack = program.getStack();
269276
DataWord receiverAddressWord = stack.get(stack.size() - 3);
270277
if (isDeadAccount(program, receiverAddressWord)) {
@@ -306,7 +313,27 @@ public static long getUnDelegateResourceCost(Program ignored) {
306313
}
307314

308315
public static long getVoteWitnessCost(Program program) {
316+
Stack stack = program.getStack();
317+
long oldMemSize = program.getMemSize();
318+
DataWord amountArrayLength = stack.get(stack.size() - 1).clone();
319+
DataWord amountArrayOffset = stack.get(stack.size() - 2);
320+
DataWord witnessArrayLength = stack.get(stack.size() - 3).clone();
321+
DataWord witnessArrayOffset = stack.get(stack.size() - 4);
322+
323+
DataWord wordSize = new DataWord(DataWord.WORD_SIZE);
324+
325+
amountArrayLength.mul(wordSize);
326+
BigInteger amountArrayMemoryNeeded = memNeeded(amountArrayOffset, amountArrayLength);
327+
328+
witnessArrayLength.mul(wordSize);
329+
BigInteger witnessArrayMemoryNeeded = memNeeded(witnessArrayOffset, witnessArrayLength);
330+
331+
return VOTE_WITNESS + calcMemEnergy(oldMemSize,
332+
(amountArrayMemoryNeeded.compareTo(witnessArrayMemoryNeeded) > 0
333+
? amountArrayMemoryNeeded : witnessArrayMemoryNeeded), 0, Op.VOTEWITNESS);
334+
}
309335

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

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

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

325354
return VOTE_WITNESS + calcMemEnergy(oldMemSize,

actuator/src/main/java/org/tron/core/vm/OperationRegistry.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ public static JumpTable getTable() {
6767
adjustMemOperations(table);
6868
}
6969

70+
if (VMConfig.allowEnergyAdjustment()) {
71+
ajustForFairEnergy(table);
72+
}
73+
7074
return table;
7175
}
7276

@@ -635,4 +639,17 @@ public static void appendShangHaiOperations(JumpTable table) {
635639
OperationActions::push0Action,
636640
proposal));
637641
}
642+
643+
public static void ajustForFairEnergy(JumpTable table) {
644+
table.set(new Operation(
645+
Op.VOTEWITNESS, 4, 1,
646+
EnergyCost::getVoteWitnessCost2,
647+
OperationActions::voteWitnessAction,
648+
VMConfig::allowTvmVote));
649+
650+
table.set(new Operation(
651+
Op.SUICIDE, 1, 0,
652+
EnergyCost::getSuicideCost2,
653+
OperationActions::suicideAction));
654+
}
638655
}

actuator/src/main/java/org/tron/core/vm/VMUtils.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
import java.io.InputStream;
1313
import java.io.OutputStream;
1414
import java.util.Arrays;
15-
import java.util.Map;
1615
import java.util.zip.Deflater;
1716
import java.util.zip.DeflaterOutputStream;
1817
import lombok.extern.slf4j.Slf4j;
1918
import org.tron.common.utils.ByteArray;
2019
import org.tron.common.utils.ByteUtil;
2120
import org.tron.common.utils.Commons;
2221
import org.tron.common.utils.DecodeUtil;
22+
import org.tron.core.Constant;
2323
import org.tron.core.capsule.AccountCapsule;
2424
import org.tron.core.exception.ContractValidateException;
2525
import org.tron.core.vm.config.VMConfig;
@@ -33,6 +33,11 @@ public final class VMUtils {
3333
private VMUtils() {
3434
}
3535

36+
public static int getAddressSize() {
37+
return VMConfig.allowEnergyAdjustment() ?
38+
Constant.TRON_ADDRESS_SIZE : Constant.STANDARD_ADDRESS_SIZE;
39+
}
40+
3641
public static void closeQuietly(Closeable closeable) {
3742
try {
3843
if (closeable != null) {

actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public static void load(StoreFactory storeFactory) {
3939
VMConfig.initDynamicEnergyIncreaseFactor(ds.getDynamicEnergyIncreaseFactor());
4040
VMConfig.initDynamicEnergyMaxFactor(ds.getDynamicEnergyMaxFactor());
4141
VMConfig.initAllowTvmShangHai(ds.getAllowTvmShangHai());
42+
VMConfig.initAllowEnergyAdjustment(ds.getAllowEnergyAdjustment());
4243
}
4344
}
4445
}

actuator/src/main/java/org/tron/core/vm/config/VMConfig.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class VMConfig {
4949

5050
private static boolean ALLOW_TVM_SHANGHAI = false;
5151

52+
private static boolean ALLOW_ENERGY_ADJUSTMENT = false;
53+
5254
private VMConfig() {
5355
}
5456

@@ -136,6 +138,10 @@ public static void initAllowTvmShangHai(long allow) {
136138
ALLOW_TVM_SHANGHAI = allow == 1;
137139
}
138140

141+
public static void initAllowEnergyAdjustment(long allow) {
142+
ALLOW_ENERGY_ADJUSTMENT = allow == 1;
143+
}
144+
139145
public static boolean getEnergyLimitHardFork() {
140146
return CommonParameter.ENERGY_LIMIT_HARD_FORK;
141147
}
@@ -211,4 +217,8 @@ public static long getDynamicEnergyMaxFactor() {
211217
public static boolean allowTvmShanghai() {
212218
return ALLOW_TVM_SHANGHAI;
213219
}
220+
221+
public static boolean allowEnergyAdjustment() {
222+
return ALLOW_ENERGY_ADJUSTMENT;
223+
}
214224
}

actuator/src/main/java/org/tron/core/vm/program/Program.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,8 @@ public void suicide(DataWord obtainerAddress) {
457457
InternalTransaction internalTx = addInternalTx(null, owner, obtainer, balance, null,
458458
"suicide", nonce, getContractState().getAccount(owner).getAssetMapV2());
459459

460-
if (FastByteComparisons.compareTo(owner, 0, 20, obtainer, 0, 20) == 0) {
460+
int ADDRESS_SIZE = VMUtils.getAddressSize();
461+
if (FastByteComparisons.compareTo(owner, 0, ADDRESS_SIZE, obtainer, 0, ADDRESS_SIZE) == 0) {
461462
// if owner == obtainer just zeroing account according to Yellow Paper
462463
getContractState().addBalance(owner, -balance);
463464
byte[] blackHoleAddress = getContractState().getBlackHoleAddress();

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>
219219

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

222+
private static final byte[] ALLOW_ENERGY_ADJUSTMENT = "ALLOW_FAIR_ENERGY_ADJUSTMENT".getBytes();
223+
222224
@Autowired
223225
private DynamicPropertiesStore(@Value("properties") String dbName) {
224226
super(dbName);
@@ -2850,6 +2852,17 @@ public long getAllowOldRewardOpt() {
28502852
.orElse(CommonParameter.getInstance().getAllowOldRewardOpt());
28512853
}
28522854

2855+
public void saveAllowEnergyAdjustment(long allowEnergyAdjustment) {
2856+
this.put(ALLOW_ENERGY_ADJUSTMENT, new BytesCapsule(ByteArray.fromLong(allowEnergyAdjustment)));
2857+
}
2858+
2859+
public long getAllowEnergyAdjustment() {
2860+
return Optional.ofNullable(getUnchecked(ALLOW_ENERGY_ADJUSTMENT))
2861+
.map(BytesCapsule::getData)
2862+
.map(ByteArray::toLong)
2863+
.orElse(CommonParameter.getInstance().getAllowEnergyAdjustment());
2864+
}
2865+
28532866
private static class DynamicResourceProperties {
28542867

28552868
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
@@ -666,6 +666,10 @@ public class CommonParameter {
666666
@Setter
667667
public long allowOldRewardOpt;
668668

669+
@Getter
670+
@Setter
671+
public long allowEnergyAdjustment;
672+
669673
private static double calcMaxTimeRatio() {
670674
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
671675
return 5.0;

0 commit comments

Comments
 (0)