Skip to content
Closed
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
14 changes: 12 additions & 2 deletions actuator/src/main/java/org/tron/core/actuator/VMActuator.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import static org.tron.common.math.Maths.floorDiv;
import static org.tron.common.math.Maths.max;
import static org.tron.common.math.Maths.min;
import static org.tron.core.vm.PrecompiledContracts.BURN_NOT_ALLOWED;
import static org.tron.core.vm.PrecompiledContracts.MINT_NOT_ALLOWED;
import static org.tron.core.vm.PrecompiledContracts.TRANSFER_NOT_ALLOWED;
import static org.tron.protos.contract.Common.ResourceCode.ENERGY;

import com.google.protobuf.ByteString;
Expand Down Expand Up @@ -231,7 +234,12 @@ public void execute(Object object) throws ContractExeException {
return;
}

if (result.getException() != null || result.isRevert()) {
String errorString = result.getRuntimeError();
boolean shieldedProofNotAllowed = MINT_NOT_ALLOWED.equals(errorString)
|| TRANSFER_NOT_ALLOWED.equals(errorString)
|| BURN_NOT_ALLOWED.equals(errorString);

if (result.getException() != null || result.isRevert() || shieldedProofNotAllowed) {
result.getDeleteAccounts().clear();
result.getLogInfoList().clear();
//result.resetFutureRefund();
Expand All @@ -243,6 +251,9 @@ public void execute(Object object) throws ContractExeException {
}
result.setRuntimeError(result.getException().getMessage());
throw result.getException();
} else if (shieldedProofNotAllowed) {
// Runtime error already set by the precompile; just mark the revert (no energy burn).
result.setRevert();
} else {
result.setRuntimeError("REVERT opcode executed");
}
Expand All @@ -254,7 +265,6 @@ public void execute(Object object) throws ContractExeException {
.parseLogInfos(program.getResult().getLogInfoList(), rootRepository);
program.getResult().setTriggerList(triggers);
}

}
} else {
rootRepository.commit();
Expand Down
13 changes: 13 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 @@ -13,6 +13,7 @@
import org.tron.core.config.Parameter.ForkBlockVersionEnum;
import org.tron.core.exception.ContractValidateException;
import org.tron.core.store.DynamicPropertiesStore;
import org.tron.core.vm.PrecompiledContracts;

public class ProposalUtil {

Expand Down Expand Up @@ -941,6 +942,17 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
}
break;
}
case CLOSE_SHIELDED_TRC20_TRANSACTION: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_8_2)) {
throw new ContractValidateException(
"Bad chain parameter id [CLOSE_SHIELDED_TRC20_TRANSACTION]");
}
if (value < 0 || value > 3) {
throw new ContractValidateException(
"This value[CLOSE_SHIELDED_TRC20_TRANSACTION] is only allowed to be in the range 0-3");
}
break;
}
default:
break;
}
Expand Down Expand Up @@ -1018,6 +1030,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
CLOSE_SHIELDED_TRC20_TRANSACTION(80), // 0, {0,1,2,3}
ALLOW_ENERGY_ADJUSTMENT(81), // 0, 1
MAX_CREATE_ACCOUNT_TX_SIZE(82), // [500, 10000]
ALLOW_TVM_CANCUN(83), // 0, 1
Expand Down
27 changes: 27 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,15 @@ public class PrecompiledContracts {
private static final DataWord p256VerifyAddr = new DataWord(
"0000000000000000000000000000000000000000000000000000000000000100");

public static final String MINT_NOT_ALLOWED = "shield trc20 mint not allowed";
public static final String TRANSFER_NOT_ALLOWED = "shield trc20 transfer not allowed";
public static final String BURN_NOT_ALLOWED = "shield trc20 burn not allowed";

// Staged values of closeShieldedTRC20Transaction(): operation (mint < transfer < burn);
public static final long CLOSE_SHIELDED_TRC20_MINT = 1;
public static final long CLOSE_SHIELDED_TRC20_TRANSFER = 2;
public static final long CLOSE_SHIELDED_TRC20_BURN = 3;

public static PrecompiledContract getOptimizedContractForConstant(PrecompiledContract contract) {
try {
Constructor<?> constructor = contract.getClass().getDeclaredConstructor();
Expand Down Expand Up @@ -1385,6 +1394,12 @@ public long getEnergyForData(byte[] data) {

@Override
public Pair<Boolean, byte[]> execute(byte[] data) {
// Mint closed (CLOSE_SHIELDED_TRC20_TRANSACTION level >= 1). Return success (the Boolean
// is the CALL success flag) so the caller's unused energy is refunded -- failing here
// would "spend all energy". Zero payload + a REVERT (set via runtimeError) still revert.
if (VMConfig.closeShieldedTRC20Transaction() >= CLOSE_SHIELDED_TRC20_MINT) {
return Pair.of(true, DataWord.ZERO().getData());
}
if (data == null) {
return Pair.of(true, DataWord.ZERO().getData());
}
Expand Down Expand Up @@ -1463,6 +1478,12 @@ public long getEnergyForData(byte[] data) {

@Override
public Pair<Boolean, byte[]> execute(byte[] data) {
// Transfer closed (CLOSE_SHIELDED_TRC20_TRANSACTION level >= 2). Return success (the Boolean
// is the CALL success flag) so the caller's unused energy is refunded -- failing here
// would "spend all energy". Zero payload + a REVERT (set via runtimeError) still revert.
if (VMConfig.closeShieldedTRC20Transaction() >= CLOSE_SHIELDED_TRC20_TRANSFER) {
return Pair.of(true, DataWord.ZERO().getData());
}
if (data == null) {
return Pair.of(true, DataWord.ZERO().getData());
}
Expand Down Expand Up @@ -1740,6 +1761,12 @@ public long getEnergyForData(byte[] data) {

@Override
public Pair<Boolean, byte[]> execute(byte[] data) {
// Burn closed (CLOSE_SHIELDED_TRC20_TRANSACTION level >= 3). Return success (the Boolean
// is the CALL success flag) so the caller's unused energy is refunded -- failing here
// would "spend all energy". Zero payload + a REVERT (set via runtimeError) still revert.
if (VMConfig.closeShieldedTRC20Transaction() >= CLOSE_SHIELDED_TRC20_BURN) {
return Pair.of(true, DataWord.ZERO().getData());
}
if (data == null) {
return Pair.of(true, DataWord.ZERO().getData());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static void load(StoreFactory storeFactory) {
VMConfig.initAllowTvmConstantinople(ds.getAllowTvmConstantinople());
VMConfig.initAllowTvmSolidity059(ds.getAllowTvmSolidity059());
VMConfig.initAllowShieldedTRC20Transaction(ds.getAllowShieldedTRC20Transaction());
VMConfig.initCloseShieldedTRC20Transaction(ds.getCloseShieldedTRC20Transaction());
VMConfig.initAllowTvmIstanbul(ds.getAllowTvmIstanbul());
VMConfig.initAllowTvmFreeze(ds.getAllowTvmFreeze());
VMConfig.initAllowTvmVote(ds.getAllowTvmVote());
Expand Down
25 changes: 25 additions & 0 deletions actuator/src/main/java/org/tron/core/vm/program/Program.java
Original file line number Diff line number Diff line change
Expand Up @@ -1743,6 +1743,8 @@ public void callToPrecompiledAddress(MessageCall msg,
this.refundEnergy(msg.getEnergy().longValue() - requiredEnergy, CALL_PRE_COMPILED);
this.stackPushOne();
returnDataBuffer = out.getRight();

markClosedShieldedTRC20Precompile(contract);
deposit.commit();
} else {
// spend all energy on failure, push zero and revert state changes
Expand All @@ -1761,6 +1763,29 @@ public void callToPrecompiledAddress(MessageCall msg,
}
}

// When the shielded TRC20 kill-switch is engaged, the proof precompile returns success so the
// caller's unused energy is refunded (see PrecompiledContracts); we only flag the closed
// operation here via a runtime error, which VMActuator later turns into a REVERT.
private void markClosedShieldedTRC20Precompile(
PrecompiledContracts.PrecompiledContract contract) {
long phase = VMConfig.closeShieldedTRC20Transaction();
if (phase == 0) {
return;
}
if (contract instanceof PrecompiledContracts.VerifyMintProof
&& phase >= PrecompiledContracts.CLOSE_SHIELDED_TRC20_MINT) {
this.result.setRuntimeError(PrecompiledContracts.MINT_NOT_ALLOWED);
}
if (contract instanceof PrecompiledContracts.VerifyTransferProof
&& phase >= PrecompiledContracts.CLOSE_SHIELDED_TRC20_TRANSFER) {
this.result.setRuntimeError(PrecompiledContracts.TRANSFER_NOT_ALLOWED);
}
if (contract instanceof PrecompiledContracts.VerifyBurnProof
&& phase >= PrecompiledContracts.CLOSE_SHIELDED_TRC20_BURN) {
this.result.setRuntimeError(PrecompiledContracts.BURN_NOT_ALLOWED);
}
}

public boolean byTestingSuite() {
return invoke.byTestingSuite();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>
private static final byte[] ALLOW_SHIELDED_TRC20_TRANSACTION =
"ALLOW_SHIELDED_TRC20_TRANSACTION"
.getBytes();
private static final byte[] CLOSE_SHIELDED_TRC20_TRANSACTION =
"CLOSE_SHIELDED_TRC20_TRANSACTION".getBytes();
private static final byte[] ALLOW_TVM_ISTANBUL = "ALLOW_TVM_ISTANBUL".getBytes();
private static final byte[] ALLOW_TVM_CONSTANTINOPLE = "ALLOW_TVM_CONSTANTINOPLE".getBytes();
private static final byte[] ALLOW_TVM_SOLIDITY_059 = "ALLOW_TVM_SOLIDITY_059".getBytes();
Expand Down Expand Up @@ -727,6 +729,13 @@ private DynamicPropertiesStore(@Value("properties") String dbName) {
CommonParameter.getInstance().getAllowShieldedTRC20Transaction());
}

try {
this.getCloseShieldedTRC20Transaction();
} catch (IllegalArgumentException e) {
this.saveCloseShieldedTRC20Transaction(
CommonParameter.getInstance().getCloseShieldedTRC20Transaction());
}

try {
this.getAllowTvmIstanbul();
} catch (IllegalArgumentException e) {
Expand Down Expand Up @@ -2060,6 +2069,20 @@ public long getAllowShieldedTRC20Transaction() {
() -> new IllegalArgumentException(msg));
}

public void saveCloseShieldedTRC20Transaction(long closeShieldedTRC20Transaction) {
this.put(DynamicPropertiesStore.CLOSE_SHIELDED_TRC20_TRANSACTION,
new BytesCapsule(ByteArray.fromLong(closeShieldedTRC20Transaction)));
}

public long getCloseShieldedTRC20Transaction() {
String msg = "not found CLOSE_SHIELDED_TRC20_TRANSACTION";
return Optional.ofNullable(getUnchecked(CLOSE_SHIELDED_TRC20_TRANSACTION))
.map(BytesCapsule::getData)
.map(ByteArray::toLong)
.orElseThrow(
() -> new IllegalArgumentException(msg));
}

public void saveAllowTvmIstanbul(long allowTVMIstanbul) {
this.put(DynamicPropertiesStore.ALLOW_TVM_ISTANBUL,
new BytesCapsule(ByteArray.fromLong(allowTVMIstanbul)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,9 @@ public class CommonParameter {
public long allowShieldedTRC20Transaction;
@Getter
@Setter
public long closeShieldedTRC20Transaction;
@Getter
@Setter
public long allowTvmIstanbul;
@Getter
@Setter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class CommitteeConfig {
private long allowTvmSolidity059 = 0;
private long forbidTransferToContract = 0;
private long allowShieldedTRC20Transaction = 0;
private long closeShieldedTRC20Transaction = 0;
private long allowMarketTransaction = 0;
private long allowTransactionFeePool = 0;
private long allowBlackHoleOptimization = 0;
Expand Down
10 changes: 10 additions & 0 deletions common/src/main/java/org/tron/core/vm/config/VMConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class VMConfig {

private static boolean ALLOW_SHIELDED_TRC20_TRANSACTION = false;

private static long CLOSE_SHIELDED_TRC20_TRANSACTION = 0;

private static boolean ALLOW_TVM_ISTANBUL = false;

private static boolean ALLOW_TVM_FREEZE = false;
Expand Down Expand Up @@ -100,6 +102,10 @@ public static void initAllowShieldedTRC20Transaction(long allow) {
ALLOW_SHIELDED_TRC20_TRANSACTION = allow == 1;
}

public static void initCloseShieldedTRC20Transaction(long close) {
CLOSE_SHIELDED_TRC20_TRANSACTION = close;
}

public static void initAllowTvmIstanbul(long allow) {
ALLOW_TVM_ISTANBUL = allow == 1;
}
Expand Down Expand Up @@ -208,6 +214,10 @@ public static boolean allowShieldedTRC20Transaction() {
return ALLOW_SHIELDED_TRC20_TRANSACTION;
}

public static long closeShieldedTRC20Transaction() {
return CLOSE_SHIELDED_TRC20_TRANSACTION;
}

public static boolean allowTvmIstanbul() {
return ALLOW_TVM_ISTANBUL;
}
Expand Down
1 change: 1 addition & 0 deletions common/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,7 @@ committee = {
allowTvmSolidity059 = 0 # getAllowTvmSolidity059, #32: enable Solidity 0.5.9 TVM rules
forbidTransferToContract = 0 # getForbidTransferToContract, #35: forbid direct transfers to contracts
allowShieldedTRC20Transaction = 0 # getAllowShieldedTRC20Transaction, #39: enable shielded TRC20 transfers
closeShieldedTRC20Transaction = 0 # getCloseShieldedTRC20Transaction, #80: progressively close shielded TRC20 mint(1)/transfer(2)/burn(3); range 0-3
allowTvmIstanbul = 0 # getAllowTvmIstanbul, #41: enable Istanbul TVM rules
allowMarketTransaction = 0 # getAllowMarketTransaction, #44: enable market transactions
allowProtoFilterNum = 0 # getAllowProtoFilterNum, #24: enable protobuf field-number filtering
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 @@ -1507,6 +1507,11 @@ public Protocol.ChainParameters getChainParameters() {
.setValue(dbManager.getDynamicPropertiesStore().getAllowHardenExchangeCalculation())
.build());

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

return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ private static void applyCommitteeConfig(CommitteeConfig cc) {
PARAMETER.allowTvmSolidity059 = cc.getAllowTvmSolidity059();
PARAMETER.forbidTransferToContract = cc.getForbidTransferToContract();
PARAMETER.allowShieldedTRC20Transaction = cc.getAllowShieldedTRC20Transaction();
PARAMETER.closeShieldedTRC20Transaction = cc.getCloseShieldedTRC20Transaction();
PARAMETER.allowMarketTransaction = cc.getAllowMarketTransaction();
PARAMETER.allowTransactionFeePool = cc.getAllowTransactionFeePool();
PARAMETER.allowBlackHoleOptimization = cc.getAllowBlackHoleOptimization();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule)
manager.getDynamicPropertiesStore().saveAllowOldRewardOpt(entry.getValue());
break;
}
case CLOSE_SHIELDED_TRC20_TRANSACTION: {
manager.getDynamicPropertiesStore().saveCloseShieldedTRC20Transaction(entry.getValue());
break;
}
case ALLOW_ENERGY_ADJUSTMENT: {
manager.getDynamicPropertiesStore().saveAllowEnergyAdjustment(entry.getValue());
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,44 @@ public void tvmFreezeV2SwitchTest() {
Assert.assertNotNull(totalAcquiredResourcePcc);
}

@Test
public void closeShieldedTRC20TransactionTest() {
// With the kill-switch engaged at the matching level, each shielded proof
// precompile short-circuits to (success, 32 zero bytes) as the very first step of
// execute(), before the null/size guards run. The input contents and length are
// therefore irrelevant here; these arrays are just non-null placeholders.
byte[] zero = DataWord.ZERO().getData();
PrecompiledContracts.VerifyMintProof mint = new PrecompiledContracts.VerifyMintProof();
PrecompiledContracts.VerifyTransferProof transfer =
new PrecompiledContracts.VerifyTransferProof();
PrecompiledContracts.VerifyBurnProof burn = new PrecompiledContracts.VerifyBurnProof();
byte[] mintData = new byte[1];
byte[] transferData = new byte[1];
byte[] burnData = new byte[1];
try {
// level 1 closes mint
VMConfig.initCloseShieldedTRC20Transaction(1);
Assert.assertEquals(1L, VMConfig.closeShieldedTRC20Transaction());
Pair<Boolean, byte[]> r = mint.execute(mintData);
Assert.assertTrue(r.getLeft());
Assert.assertArrayEquals(zero, r.getRight());

// level 2 also closes transfer
VMConfig.initCloseShieldedTRC20Transaction(2);
r = transfer.execute(transferData);
Assert.assertTrue(r.getLeft());
Assert.assertArrayEquals(zero, r.getRight());

// level 3 also closes burn
VMConfig.initCloseShieldedTRC20Transaction(3);
r = burn.execute(burnData);
Assert.assertTrue(r.getLeft());
Assert.assertArrayEquals(zero, r.getRight());
} finally {
VMConfig.initCloseShieldedTRC20Transaction(0);
}
}

@Test
public void delegatableResourceTest() {
VMConfig.initAllowTvmFreezeV2(1L);
Expand Down
Loading
Loading