From 45e3bf88ca73dacee93477572e1775fa499e0639 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Tue, 13 Jan 2026 01:16:39 +0800 Subject: [PATCH 1/2] feat(*): disable exchange transaction (#6507) --- .../java/org/tron/core/config/Parameter.java | 5 +- .../main/java/org/tron/core/db/Manager.java | 30 +++++ .../main/java/org/tron/program/Version.java | 2 +- .../ExchangeTransactionActuatorTest.java | 105 +++++++++++++++++- 4 files changed, 138 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/org/tron/core/config/Parameter.java b/common/src/main/java/org/tron/core/config/Parameter.java index a71dc58e8bd..c0e1bb06470 100644 --- a/common/src/main/java/org/tron/core/config/Parameter.java +++ b/common/src/main/java/org/tron/core/config/Parameter.java @@ -26,7 +26,8 @@ public enum ForkBlockVersionEnum { VERSION_4_7_4(29, 1596780000000L, 80), VERSION_4_7_5(30, 1596780000000L, 80), VERSION_4_7_7(31, 1596780000000L, 80), - VERSION_4_8_0(32, 1596780000000L, 80); + VERSION_4_8_0(32, 1596780000000L, 80), + VERSION_4_8_0_1(33, 1596780000000L, 70); // if add a version, modify BLOCK_VERSION simultaneously @Getter @@ -75,7 +76,7 @@ public class ChainConstant { public static final int SINGLE_REPEAT = 1; public static final int BLOCK_FILLED_SLOTS_NUMBER = 128; public static final int MAX_FROZEN_NUMBER = 1; - public static final int BLOCK_VERSION = 32; + public static final int BLOCK_VERSION = 33; public static final long FROZEN_PERIOD = 86_400_000L; public static final long DELEGATE_PERIOD = 3 * 86_400_000L; public static final long TRX_PRECISION = 1000_000L; diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 1eecc103874..8c14f280077 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -97,6 +97,7 @@ import org.tron.core.capsule.TransactionRetCapsule; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.capsule.utils.TransactionUtil; +import org.tron.core.config.Parameter; import org.tron.core.config.Parameter.ChainConstant; import org.tron.core.config.args.Args; import org.tron.core.consensus.ProposalController; @@ -873,6 +874,11 @@ public boolean pushTransaction(final TransactionCapsule trx) return true; } + if (isExchangeTransaction(trx.getInstance())) { + throw new ContractValidateException("ExchangeTransactionContract is rejected"); + } + + pushTransactionQueue.add(trx); Metrics.gaugeInc(MetricKeys.Gauge.MANAGER_QUEUE, 1, MetricLabels.Gauge.QUEUE_QUEUED); @@ -1676,6 +1682,11 @@ public BlockCapsule generateBlock(Miner miner, long blockTime, long timeout) { accountSet.add(ownerAddress); } } + + if (isExchangeTransaction(transaction)) { + continue; + } + if (ownerAddressSet.contains(ownerAddress)) { trx.setVerified(false); } @@ -1749,6 +1760,24 @@ private boolean isShieldedTransaction(Transaction transaction) { } } + private boolean isExchangeTransaction(Transaction transaction) { + Contract contract = transaction.getRawData().getContract(0); + switch (contract.getType()) { + case ExchangeTransactionContract: { + return true; + } + default: + return false; + } + } + + private void rejectExchangeTransaction(Transaction transaction) throws ContractValidateException { + if (isExchangeTransaction(transaction) && chainBaseManager.getForkController() + .pass(Parameter.ForkBlockVersionEnum.VERSION_4_8_0_1)) { + throw new ContractValidateException("ExchangeTransactionContract is rejected"); + } + } + public TransactionStore getTransactionStore() { return chainBaseManager.getTransactionStore(); } @@ -1803,6 +1832,7 @@ private void processBlock(BlockCapsule block, List txs) List results = new ArrayList<>(); long num = block.getNum(); for (TransactionCapsule transactionCapsule : block.getTransactions()) { + rejectExchangeTransaction(transactionCapsule.getInstance()); if (chainBaseManager.getDynamicPropertiesStore().allowConsensusLogicOptimization() && transactionCapsule.retCountIsGreatThanContractCount()) { throw new BadBlockException(String.format("The result count %d of this transaction %s is " diff --git a/framework/src/main/java/org/tron/program/Version.java b/framework/src/main/java/org/tron/program/Version.java index 4e9528ee50e..5bd9217ee09 100644 --- a/framework/src/main/java/org/tron/program/Version.java +++ b/framework/src/main/java/org/tron/program/Version.java @@ -4,7 +4,7 @@ public class Version { public static final String VERSION_NAME = "GreatVoyage-v4.7.7-243-gb3555dd655"; public static final String VERSION_CODE = "18631"; - private static final String VERSION = "4.8.0"; + private static final String VERSION = "4.8.0.1"; public static String getVersion() { return VERSION; diff --git a/framework/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java index d39706e0699..fbce246101e 100644 --- a/framework/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java @@ -1,10 +1,13 @@ package org.tron.core.actuator; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import static org.tron.core.config.Parameter.ChainSymbol.TRX_SYMBOL_BYTES; import com.google.protobuf.Any; import com.google.protobuf.ByteString; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.Map; import junit.framework.TestCase; @@ -13,18 +16,30 @@ import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; +import org.tron.common.crypto.ECKey; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.ForkController; +import org.tron.common.utils.PublicMethod; +import org.tron.consensus.base.Param; +import org.tron.consensus.base.Param.Miner; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.AssetIssueCapsule; +import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.capsule.WitnessCapsule; +import org.tron.core.config.Parameter; +import org.tron.core.config.Parameter.ForkBlockVersionEnum; import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ItemNotFoundException; import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; import org.tron.protos.Protocol.Transaction.Result.code; import org.tron.protos.contract.AssetIssueContractOuterClass; import org.tron.protos.contract.AssetIssueContractOuterClass.AssetIssueContract; @@ -1674,7 +1689,7 @@ public void noContract() { public void invalidContractType() { ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(); // create AssetIssueContract, not a valid ClearABI contract , which will throw e expectipon - Any invalidContractTypes = Any.pack(AssetIssueContractOuterClass.AssetIssueContract.newBuilder() + Any invalidContractTypes = Any.pack(AssetIssueContract.newBuilder() .build()); actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setAny(invalidContractTypes); @@ -1725,4 +1740,92 @@ private void processAndCheckInvalid(ExchangeTransactionActuator actuator, } } + /** + * isExchangeTransaction + */ + @Test + public void isExchangeTransactionPush() { + try { + TransactionCapsule transactionCap = new TransactionCapsule( + ExchangeTransactionContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_SECOND))) + .setExchangeId(1) + .setTokenId(ByteString.copyFrom("_".getBytes())) + .setQuant(1) + .setExpected(1) + .build(), ContractType.ExchangeTransactionContract); + dbManager.pushTransaction(transactionCap); + + } catch (Exception e) { + Assert.assertTrue(true); + } + } + + @Test + public void isExchangeTransactionGenerate() { + try { + + String key = PublicMethod.getRandomPrivateKey(); + byte[] privateKey = ByteArray.fromHexString(key); + final ECKey ecKey = ECKey.fromPrivate(privateKey); + byte[] address = ecKey.getAddress(); + WitnessCapsule witnessCapsule = new WitnessCapsule(ByteString.copyFrom(address)); + + String OWNER_ADDRESS_SECOND = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + TransactionCapsule transactionCap = new TransactionCapsule( + ExchangeTransactionContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_SECOND))) + .setExchangeId(1) + .setTokenId(ByteString.copyFrom("_".getBytes())) + .setQuant(1) + .setExpected(1) + .build(), ContractType.ExchangeTransactionContract); + dbManager.getPendingTransactions().add(transactionCap); + Param param = Param.getInstance(); + Miner miner = param.new Miner(privateKey, witnessCapsule.getAddress(), + witnessCapsule.getAddress()); + BlockCapsule blockCapsule = dbManager + .generateBlock(miner, 1533529947843L, System.currentTimeMillis() + 1000); + } catch (Exception e) { + Assert.assertTrue(false); + } + } + + @Test + public void rejectExchangeTransaction() { + try { + long maintenanceTimeInterval = dbManager.getDynamicPropertiesStore() + .getMaintenanceTimeInterval(); + long hardForkTime = + ((ForkBlockVersionEnum.VERSION_4_0_1.getHardForkTime() - 1) / maintenanceTimeInterval + 1) + * maintenanceTimeInterval; + dbManager.getDynamicPropertiesStore() + .saveLatestBlockHeaderTimestamp(hardForkTime + 1); + byte[] stats = new byte[27]; + Arrays.fill(stats, (byte) 1); + dbManager.getDynamicPropertiesStore() + .statsByVersion(ForkBlockVersionEnum.VERSION_4_8_0_1.getValue(), stats); + boolean flag = ForkController.instance().pass(ForkBlockVersionEnum.VERSION_4_8_0_1); + Assert.assertTrue(flag); + String OWNER_ADDRESS_SECOND = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + TransactionCapsule transactionCap = new TransactionCapsule( + ExchangeTransactionContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_SECOND))) + .setExchangeId(1) + .setTokenId(ByteString.copyFrom("_".getBytes())) + .setQuant(1) + .setExpected(1) + .build(), ContractType.ExchangeTransactionContract); + Method rejectExchangeTransaction = Manager.class.getDeclaredMethod( + "rejectExchangeTransaction", org.tron.protos.Protocol.Transaction.class); + rejectExchangeTransaction.setAccessible(true); + Exception ex = assertThrows(InvocationTargetException.class, () -> { + rejectExchangeTransaction.invoke(dbManager, transactionCap.getInstance()); + }); + } catch (Exception e) { + fail(); + } + } } From 25b35f514833c0a7024e42beeb2c03c539580138 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Tue, 13 Jan 2026 01:23:47 +0800 Subject: [PATCH 2/2] update a new version. version name:GreatVoyage-v4.8.0-1-g45e3bf88ca,version code:18634 (#6508) --- framework/src/main/java/org/tron/program/Version.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/program/Version.java b/framework/src/main/java/org/tron/program/Version.java index 5bd9217ee09..6dde9a8e52c 100644 --- a/framework/src/main/java/org/tron/program/Version.java +++ b/framework/src/main/java/org/tron/program/Version.java @@ -2,8 +2,8 @@ public class Version { - public static final String VERSION_NAME = "GreatVoyage-v4.7.7-243-gb3555dd655"; - public static final String VERSION_CODE = "18631"; + public static final String VERSION_NAME = "GreatVoyage-v4.8.0-1-g45e3bf88ca"; + public static final String VERSION_CODE = "18634"; private static final String VERSION = "4.8.0.1"; public static String getVersion() {