Skip to content

Commit

Permalink
Merge pull request #5843 from tronprotocol/master
Browse files Browse the repository at this point in the history
Master merge to develop
  • Loading branch information
lvs007 authored May 30, 2024
2 parents 76df76c + a8ad2a1 commit afd15a7
Show file tree
Hide file tree
Showing 38 changed files with 668 additions and 55 deletions.
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
35 changes: 34 additions & 1 deletion actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.tron.core.utils;

import static org.tron.core.Constant.CREATE_ACCOUNT_TRANSACTION_MAX_BYTE_SIZE;
import static org.tron.core.Constant.CREATE_ACCOUNT_TRANSACTION_MIN_BYTE_SIZE;
import static org.tron.core.Constant.DYNAMIC_ENERGY_INCREASE_FACTOR_RANGE;
import static org.tron.core.Constant.DYNAMIC_ENERGY_MAX_FACTOR_RANGE;
import static org.tron.core.config.Parameter.ChainConstant.ONE_YEAR_BLOCK_NUMBERS;
Expand Down Expand Up @@ -748,6 +750,35 @@ 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(
"Bad chain parameter id [MAX_CREATE_ACCOUNT_TX_SIZE]");
}
if (value < CREATE_ACCOUNT_TRANSACTION_MIN_BYTE_SIZE
|| value > CREATE_ACCOUNT_TRANSACTION_MAX_BYTE_SIZE) {
throw new ContractValidateException(
"This value[MAX_CREATE_ACCOUNT_TX_SIZE] is only allowed to be greater than or equal "
+ "to " + CREATE_ACCOUNT_TRANSACTION_MIN_BYTE_SIZE + " and less than or equal to "
+ CREATE_ACCOUNT_TRANSACTION_MAX_BYTE_SIZE + "!");
}
break;
}
default:
break;
}
Expand Down Expand Up @@ -824,7 +855,9 @@ public enum ProposalType { // current value, value range
ALLOW_TVM_SHANGHAI(76), // 0, 1
ALLOW_CANCEL_ALL_UNFREEZE_V2(77), // 0, 1
MAX_DELEGATE_LOCK_PERIOD(78), // (86400, 10512000]
ALLOW_OLD_REWARD_OPT(79); // 0, 1
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 @@ -17,6 +17,7 @@

import static org.tron.common.utils.StringUtil.encode58Check;
import static org.tron.common.utils.WalletUtil.checkPermissionOperations;
import static org.tron.core.Constant.MAX_CONTRACT_RESULT_SIZE;
import static org.tron.core.exception.P2pException.TypeEnum.PROTOBUF_ERROR;

import com.google.common.primitives.Bytes;
Expand Down Expand Up @@ -114,6 +115,9 @@ public class TransactionCapsule implements ProtoCapsule<Transaction> {
@Getter
@Setter
private boolean isTransactionCreate = false;
@Getter
@Setter
private boolean isInBlock = false;

public byte[] getOwnerAddress() {
if (this.ownerAddress == null) {
Expand Down Expand Up @@ -730,6 +734,15 @@ public long getResultSerializedSize() {
return size;
}

public long getResultSizeWithMaxContractRet() {
long size = 0;
for (Result result : this.transaction.getRetList()) {
size += result.toBuilder().clearContractRet().build().getSerializedSize()
+ MAX_CONTRACT_RESULT_SIZE;
}
return size;
}

@Override
public Transaction getInstance() {
return this.transaction;
Expand Down Expand Up @@ -842,4 +855,18 @@ public BalanceContract.TransferContract getTransferContract() {
return null;
}
}

public void removeRedundantRet() {
Transaction tx = this.getInstance();
List<Result> tmpList = new ArrayList<>(tx.getRetList());
int contractCount = tx.getRawData().getContractCount();
if (tx.getRetCount() > contractCount && contractCount > 0) {
Transaction.Builder transactionBuilder = tx.toBuilder().clearRet();
for (int i = 0; i < contractCount; i++) {
Result result = tmpList.get(i);
transactionBuilder.addRet(result);
}
this.transaction = transactionBuilder.build();
}
}
}
25 changes: 22 additions & 3 deletions chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.tron.core.db;

import static org.tron.core.Constant.PER_SIGN_LENGTH;
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;
import static org.tron.protos.Protocol.Transaction.Contract.ContractType.ShieldedTransferContract;
import static org.tron.protos.Protocol.Transaction.Contract.ContractType.TransferAssetContract;
import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH;

import com.google.protobuf.ByteString;
import java.util.HashMap;
Expand All @@ -19,13 +21,12 @@
import org.tron.core.capsule.TransactionCapsule;
import org.tron.core.exception.AccountResourceInsufficientException;
import org.tron.core.exception.ContractValidateException;
import org.tron.core.exception.TooBigTransactionException;
import org.tron.core.exception.TooBigTransactionResultException;
import org.tron.protos.Protocol.Transaction.Contract;
import org.tron.protos.contract.AssetIssueContractOuterClass.TransferAssetContract;
import org.tron.protos.contract.BalanceContract.TransferContract;

import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH;

@Slf4j(topic = "DB")
public class BandwidthProcessor extends ResourceProcessor {

Expand Down Expand Up @@ -95,8 +96,15 @@ public void updateUsage(AssetIssueCapsule assetIssueCapsule, long now) {
@Override
public void consume(TransactionCapsule trx, TransactionTrace trace)
throws ContractValidateException, AccountResourceInsufficientException,
TooBigTransactionResultException {
TooBigTransactionResultException, TooBigTransactionException {
List<Contract> contracts = trx.getInstance().getRawData().getContractList();
long resultSizeWithMaxContractRet = trx.getResultSizeWithMaxContractRet();
if (!trx.isInBlock() && resultSizeWithMaxContractRet >
Constant.MAX_RESULT_SIZE_IN_TX * contracts.size()) {
throw new TooBigTransactionResultException(String.format(
"Too big transaction result, TxId %s, the result size is %d bytes, maxResultSize %d",
trx.getTransactionId(), resultSizeWithMaxContractRet, Constant.MAX_RESULT_SIZE_IN_TX));
}
if (trx.getResultSerializedSize() > Constant.MAX_RESULT_SIZE_IN_TX * contracts.size()) {
throw new TooBigTransactionResultException();
}
Expand Down Expand Up @@ -127,6 +135,17 @@ public void consume(TransactionCapsule trx, TransactionTrace trace)
}
long now = chainBaseManager.getHeadSlot();
if (contractCreateNewAccount(contract)) {
if (!trx.isInBlock()) {
long maxCreateAccountTxSize = dynamicPropertiesStore.getMaxCreateAccountTxSize();
int signatureCount = trx.getInstance().getSignatureCount();
long createAccountBytesSize = trx.getInstance().toBuilder().clearRet()
.build().getSerializedSize() - (signatureCount * PER_SIGN_LENGTH);
if (createAccountBytesSize > maxCreateAccountTxSize) {
throw new TooBigTransactionException(String.format(
"Too big new account transaction, TxId %s, the size is %d bytes, maxTxSize %d",
trx.getTransactionId(), createAccountBytesSize, maxCreateAccountTxSize));
}
}
consumeForCreateNewAccount(accountCapsule, bytesSize, now, trace);
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.tron.core.exception.AccountResourceInsufficientException;
import org.tron.core.exception.BalanceInsufficientException;
import org.tron.core.exception.ContractValidateException;
import org.tron.core.exception.TooBigTransactionException;
import org.tron.core.exception.TooBigTransactionResultException;
import org.tron.core.store.AccountStore;
import org.tron.core.store.DynamicPropertiesStore;
Expand All @@ -35,7 +36,7 @@ protected ResourceProcessor(DynamicPropertiesStore dynamicPropertiesStore,
}

abstract void consume(TransactionCapsule trx, TransactionTrace trace)
throws ContractValidateException, AccountResourceInsufficientException, TooBigTransactionResultException;
throws ContractValidateException, AccountResourceInsufficientException, TooBigTransactionResultException, TooBigTransactionException;

protected long increase(long lastUsage, long usage, long lastTime, long now) {
return increase(lastUsage, usage, lastTime, now, windowSize);
Expand Down
Loading

0 comments on commit afd15a7

Please sign in to comment.