Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
31 changes: 25 additions & 6 deletions actuator/src/main/java/org/tron/core/actuator/VMActuator.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.tron.common.runtime.InternalTransaction.TrxType;
import org.tron.common.runtime.ProgramResult;
import org.tron.common.runtime.vm.DataWord;
import org.tron.common.utils.ForkController;
import org.tron.common.utils.StorageUtils;
import org.tron.common.utils.StringUtil;
import org.tron.common.utils.WalletUtil;
Expand All @@ -33,6 +34,7 @@
import org.tron.core.capsule.BlockCapsule;
import org.tron.core.capsule.ContractCapsule;
import org.tron.core.capsule.ReceiptCapsule;
import org.tron.core.config.Parameter;
import org.tron.core.db.EnergyProcessor;
import org.tron.core.db.TransactionContext;
import org.tron.core.exception.ContractExeException;
Expand Down Expand Up @@ -189,7 +191,8 @@ public void execute(Object object) throws ContractExeException {
throw e;
}

VM.play(program, OperationRegistry.getTable());
// Prepare the table once for this execution and all nested calls.
VM.play(program, OperationRegistry.prepareAndGetTable(isConstantCall));
result = program.getResult();

if (VMConfig.allowEnergyAdjustment()) {
Expand Down Expand Up @@ -217,6 +220,9 @@ public void execute(Object object) throws ContractExeException {
} else {
result.spendEnergy(saveCodeEnergy);
if (VMConfig.allowTvmConstantinople()) {
CreateSmartContract createContract =
ContractCapsule.getSmartContractFromTransaction(trx);
checkContractHashFields(createContract.getNewContract());
rootRepository.saveCode(program.getContractAddress().getNoLeadZeroesData(), code);
}
}
Expand Down Expand Up @@ -330,6 +336,7 @@ private void create()
if (contract == null) {
throw new ContractValidateException("Cannot get CreateSmartContract from transaction");
}

SmartContract newSmartContract;
if (VMConfig.allowTvmCompatibleEvm()) {
newSmartContract = contract.getNewContract().toBuilder().setVersion(1).build();
Expand All @@ -341,11 +348,7 @@ private void create()
throw new ContractValidateException("OwnerAddress is not equals OriginAddress");
}

byte[] contractName = newSmartContract.getName().getBytes();

if (contractName.length > VMConstant.CONTRACT_NAME_LENGTH) {
throw new ContractValidateException("contractName's length cannot be greater than 32");
}
checkContractNameLength(contract.getNewContract());

long percent = contract.getNewContract().getConsumeUserResourcePercent();
if (percent < 0 || percent > VMConstant.ONE_HUNDRED) {
Expand Down Expand Up @@ -455,6 +458,22 @@ private void create()

}

static void checkContractHashFields(SmartContract contract) {
if (!contract.getCodeHash().isEmpty() || !contract.getTrxHash().isEmpty()) {
MUtil.checkCPUTimeForContractHashFields();
}
}

static void checkContractNameLength(SmartContract contract) throws ContractValidateException {
int contractNameLength =
ForkController.instance().pass(Parameter.ForkBlockVersionEnum.VERSION_4_8_2_2)
? contract.getNameBytes().size()
: contract.getName().getBytes().length;
if (contractNameLength > VMConstant.CONTRACT_NAME_LENGTH) {
throw new ContractValidateException("contractName's length cannot be greater than 32");
}
}

/**
* **
*/
Expand Down
8 changes: 8 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/Operation.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,12 @@ public void execute(Program program) {
public boolean isEnabled() {
return enabled.getAsBoolean();
}

public Operation adjustCost(Function<Program, Long> newCost) {
return new Operation(opcode, require, ret, newCost, action, enabled);
}

public Operation adjustAction(Consumer<Program> newAction) {
return new Operation(opcode, require, ret, cost, newAction, enabled);
}
}
187 changes: 94 additions & 93 deletions actuator/src/main/java/org/tron/core/vm/OperationRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,45 @@

public class OperationRegistry {

private static final Operation DEFAULT_MLOAD = new Operation(
Op.MLOAD, 1, 1, EnergyCost::getMloadCost, OperationActions::mLoadAction);

private static final Operation DEFAULT_MSTORE = new Operation(
Op.MSTORE, 2, 0, EnergyCost::getMStoreCost, OperationActions::mStoreAction);

private static final Operation DEFAULT_MSTORE8 = new Operation(
Op.MSTORE8, 2, 0, EnergyCost::getMStore8Cost, OperationActions::mStore8Action);

private static final Operation ADJUSTED_MLOAD =
DEFAULT_MLOAD.adjustCost(EnergyCost::getMloadCost2);

private static final Operation ADJUSTED_MSTORE =
DEFAULT_MSTORE.adjustCost(EnergyCost::getMStoreCost2);

private static final Operation ADJUSTED_MSTORE8 =
DEFAULT_MSTORE8.adjustCost(EnergyCost::getMStore8Cost2);

private static final Operation DEFAULT_VOTEWITNESS = new Operation(
Op.VOTEWITNESS, 4, 1, EnergyCost::getVoteWitnessCost,
OperationActions::voteWitnessAction, VMConfig::allowTvmVote);

private static final Operation ADJUSTED_VOTEWITNESS =
DEFAULT_VOTEWITNESS.adjustCost(EnergyCost::getVoteWitnessCost2);

private static final Operation OSAKA_VOTEWITNESS =
DEFAULT_VOTEWITNESS.adjustCost(EnergyCost::getVoteWitnessCost3);

private static final Operation DEFAULT_SUICIDE = new Operation(
Op.SUICIDE, 1, 0, EnergyCost::getSuicideCost, OperationActions::suicideAction);

private static final Operation ADJUSTED_SUICIDE =
DEFAULT_SUICIDE.adjustCost(EnergyCost::getSuicideCost2);

private static final Operation RESTRICTED_SUICIDE =
DEFAULT_SUICIDE.adjustCost(EnergyCost::getSuicideCost3)
.adjustAction(OperationActions::suicideAction2);

public enum Version {
TRON_V1_0,
TRON_V1_1,
TRON_V1_2,
TRON_V1_3,
TRON_V1_4,
TRON_V1_5,
// add more
// TRON_V2,
Expand All @@ -21,13 +54,21 @@ public enum Version {

private static final Map<Version, JumpTable> tableMap = new HashMap<>();

// The newest version in use. Bump this when a newer operation set is added,
// together with newLatestOperationSet() below.
private static final Version LATEST_VERSION = Version.TRON_V1_5;

static {
tableMap.put(Version.TRON_V1_0, newTronV10OperationSet());
tableMap.put(Version.TRON_V1_1, newTronV11OperationSet());
tableMap.put(Version.TRON_V1_2, newTronV12OperationSet());
tableMap.put(Version.TRON_V1_3, newTronV13OperationSet());
tableMap.put(Version.TRON_V1_4, newTronV14OperationSet());
tableMap.put(Version.TRON_V1_5, newTronV15OperationSet());
tableMap.put(LATEST_VERSION, newLatestOperationSet());
}

// Constant calls get a dedicated instance of the newest table, isolated from
// the shared consensus table above.
private static final JumpTable CONSTANT_CALL_TABLE = newLatestOperationSet();

// The single place that decides which operation set is the newest.
private static JumpTable newLatestOperationSet() {
return newTronV15OperationSet();
}

public static JumpTable newTronV10OperationSet() {
Expand Down Expand Up @@ -74,28 +115,22 @@ public static JumpTable newTronV15OperationSet() {
// Just for warming up class to avoid out_of_time
public static void init() {}

public static JumpTable getTable() {
// always get the table which has the newest version
JumpTable table = tableMap.get(Version.TRON_V1_5);

// next make the corresponding changes, exclude activating opcode
if (VMConfig.allowHigherLimitForMaxCpuTimeOfOneTx()) {
adjustMemOperations(table);
}

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

if (VMConfig.allowTvmSelfdestructRestriction()) {
adjustSelfdestruct(table);
}
public static JumpTable prepareAndGetTable(boolean isConstantCall) {
JumpTable table = getTable(isConstantCall);
// Apply configuration-dependent changes once at the top level.
adjustTable(table);
return table;
}

if (VMConfig.allowTvmOsaka()) {
adjustVoteWitnessCost(table);
}
public static JumpTable getTable(boolean isConstantCall) {
return isConstantCall ? CONSTANT_CALL_TABLE : tableMap.get(LATEST_VERSION);
}

return table;
private static void adjustTable(JumpTable table) {
// Make the corresponding changes, excluding opcode activation.
adjustMemOperations(table);
adjustVoteWitness(table);
adjustSelfdestruct(table);
}

public static JumpTable newBaseOperationSet() {
Expand Down Expand Up @@ -331,20 +366,11 @@ public static JumpTable newBaseOperationSet() {
EnergyCost::getBaseTierCost,
OperationActions::popAction));

table.set(new Operation(
Op.MLOAD, 1, 1,
EnergyCost::getMloadCost,
OperationActions::mLoadAction));
table.set(DEFAULT_MLOAD);

table.set(new Operation(
Op.MSTORE, 2, 0,
EnergyCost::getMStoreCost,
OperationActions::mStoreAction));
table.set(DEFAULT_MSTORE);

table.set(new Operation(
Op.MSTORE8, 2, 0,
EnergyCost::getMStore8Cost,
OperationActions::mStore8Action));
table.set(DEFAULT_MSTORE8);

table.set(new Operation(
Op.SLOAD, 1, 1,
Expand Down Expand Up @@ -449,10 +475,7 @@ public static JumpTable newBaseOperationSet() {
EnergyCost::getRevertCost,
OperationActions::revertAction));

table.set(new Operation(
Op.SUICIDE, 1, 0,
EnergyCost::getSuicideCost,
OperationActions::suicideAction));
table.set(DEFAULT_SUICIDE);

return table;
}
Expand Down Expand Up @@ -570,11 +593,7 @@ public static void appendFreezeOperations(JumpTable table) {
public static void appendVoteOperations(JumpTable table) {
BooleanSupplier proposal = VMConfig::allowTvmVote;

table.set(new Operation(
Op.VOTEWITNESS, 4, 1,
EnergyCost::getVoteWitnessCost,
OperationActions::voteWitnessAction,
proposal));
table.set(DEFAULT_VOTEWITNESS);

table.set(new Operation(
Op.WITHDRAWREWARD, 0, 1,
Expand All @@ -593,23 +612,6 @@ public static void appendLondonOperations(JumpTable table) {
proposal));
}

public static void adjustMemOperations(JumpTable table) {
table.set(new Operation(
Op.MLOAD, 1, 1,
EnergyCost::getMloadCost2,
OperationActions::mLoadAction));

table.set(new Operation(
Op.MSTORE, 2, 0,
EnergyCost::getMStoreCost2,
OperationActions::mStoreAction));

table.set(new Operation(
Op.MSTORE8, 2, 0,
EnergyCost::getMStore8Cost2,
OperationActions::mStore8Action));
}

public static void appendFreezeV2Operations(JumpTable table) {
BooleanSupplier proposal = VMConfig::allowTvmFreezeV2;

Expand Down Expand Up @@ -664,19 +666,6 @@ public static void appendShangHaiOperations(JumpTable table) {
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));
}

public static void appendCancunOperations(JumpTable table) {
BooleanSupplier proposal = VMConfig::allowTvmCancun;
BooleanSupplier tvmBlobProposal = VMConfig::allowTvmBlob;
Expand Down Expand Up @@ -722,18 +711,30 @@ public static void appendOsakaOperations(JumpTable table) {
proposal));
}

public static void adjustSelfdestruct(JumpTable table) {
table.set(new Operation(
Op.SUICIDE, 1, 0,
EnergyCost::getSuicideCost3,
OperationActions::suicideAction2));
public static void adjustMemOperations(JumpTable table) {
boolean adjusted = VMConfig.allowHigherLimitForMaxCpuTimeOfOneTx();
table.set(adjusted ? ADJUSTED_MLOAD : DEFAULT_MLOAD);
table.set(adjusted ? ADJUSTED_MSTORE : DEFAULT_MSTORE);
table.set(adjusted ? ADJUSTED_MSTORE8 : DEFAULT_MSTORE8);
}

public static void adjustVoteWitnessCost(JumpTable table) {
table.set(new Operation(
Op.VOTEWITNESS, 4, 1,
EnergyCost::getVoteWitnessCost3,
OperationActions::voteWitnessAction,
VMConfig::allowTvmVote));
public static void adjustVoteWitness(JumpTable table) {
if (VMConfig.allowTvmOsaka()) {
table.set(OSAKA_VOTEWITNESS);
} else if (VMConfig.allowEnergyAdjustment()) {
table.set(ADJUSTED_VOTEWITNESS);
} else {
table.set(DEFAULT_VOTEWITNESS);
}
}

public static void adjustSelfdestruct(JumpTable table) {
if (VMConfig.allowTvmSelfdestructRestriction()) {
table.set(RESTRICTED_SUICIDE);
} else if (VMConfig.allowEnergyAdjustment()) {
table.set(ADJUSTED_SUICIDE);
} else {
table.set(DEFAULT_SUICIDE);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.tron.core.vm.VMConstant;
import org.tron.core.vm.nativecontract.param.CancelAllUnfreezeV2Param;
import org.tron.core.vm.repository.Repository;
import org.tron.core.vm.utils.MUtil;
import org.tron.protos.Protocol;

@Slf4j(topic = "VMProcessor")
Expand All @@ -39,6 +40,10 @@ public void validate(CancelAllUnfreezeV2Param param, Repository repo) throws Con
throw new ContractValidateException(
ACCOUNT_EXCEPTION_STR + readableOwnerAddress + NOT_EXIST_STR);
}

if (accountCapsule.hasInvalidDelegatedV2()) {
MUtil.checkCPUTimeForInvalidDelegatedV2Balance();
}
}

public Map<String, Long> execute(CancelAllUnfreezeV2Param param, Repository repo) throws ContractExeException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.core.vm.nativecontract.param.FreezeBalanceV2Param;
import org.tron.core.vm.repository.Repository;
import org.tron.core.vm.utils.MUtil;

@Slf4j(topic = "VMProcessor")
public class FreezeBalanceV2Processor {
Expand Down Expand Up @@ -63,6 +64,10 @@ public void validate(FreezeBalanceV2Param param, Repository repo) throws Contrac
"Unknown ResourceCode, valid ResourceCode[BANDWIDTH、ENERGY]");
}
}

if (repo.isSelfDestructed(ownerAddress)) {
MUtil.checkCPUTimeForFreezeV2AfterSelfDestruct();
}
}

public void execute(FreezeBalanceV2Param param, Repository repo) {
Expand Down
Loading