From 428ede2e5d3351167608634a972258c36061e601 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Sun, 28 Apr 2024 16:52:07 +0800 Subject: [PATCH 1/8] feat(consensus): optimize block production logic --- .../src/main/java/org/tron/consensus/dpos/DposTask.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/consensus/src/main/java/org/tron/consensus/dpos/DposTask.java b/consensus/src/main/java/org/tron/consensus/dpos/DposTask.java index 537fe49ae65..8d5697cdc89 100644 --- a/consensus/src/main/java/org/tron/consensus/dpos/DposTask.java +++ b/consensus/src/main/java/org/tron/consensus/dpos/DposTask.java @@ -91,6 +91,11 @@ private State produceBlock() { try { synchronized (dposService.getBlockHandle().getLock()) { + state = stateManager.getState(); + if (!State.OK.equals(state)) { + return state; + } + long slot = dposSlot.getSlot(System.currentTimeMillis() + 50); if (slot == 0) { return State.NOT_TIME_YET; From 8b4a5dddf31e49b7c86777b2a6efe609702fb825 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Sun, 28 Apr 2024 17:01:40 +0800 Subject: [PATCH 2/8] fix(net): solve the problem of concurrent access to syncBlockToFetch object --- .../java/org/tron/core/net/service/sync/SyncService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java b/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java index 1e3e18441b9..9453700df0d 100644 --- a/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java +++ b/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java @@ -321,8 +321,9 @@ private void processSyncBlock(BlockCapsule block, PeerConnection peerConnection) } for (PeerConnection peer : tronNetDelegate.getActivePeer()) { - if (blockId.equals(peer.getSyncBlockToFetch().peek())) { - peer.getSyncBlockToFetch().pop(); + BlockId bid = peer.getSyncBlockToFetch().peek(); + if (blockId.equals(bid)) { + peer.getSyncBlockToFetch().remove(bid); if (flag) { peer.setBlockBothHave(blockId); if (peer.getSyncBlockToFetch().isEmpty() && peer.isFetchAble()) { From 934e04bc8ec840431a82791ba12d6b765eb018c8 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Sun, 28 Apr 2024 16:48:42 +0800 Subject: [PATCH 3/8] feat(net): optimize block message processing logic --- .../net/messagehandler/BlockMsgHandler.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 14523df86a5..623b0140701 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -61,6 +61,18 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep BlockMessage blockMessage = (BlockMessage) msg; BlockId blockId = blockMessage.getBlockId(); + BlockCapsule blockCapsule = blockMessage.getBlockCapsule(); + if (blockCapsule.getInstance().getSerializedSize() > maxBlockSize) { + logger.error("Receive bad block {} from peer {}, block size over limit", + blockMessage.getBlockId(), peer.getInetSocketAddress()); + throw new P2pException(TypeEnum.BAD_MESSAGE, "block size over limit"); + } + long gap = blockCapsule.getTimeStamp() - System.currentTimeMillis(); + if (gap >= BLOCK_PRODUCED_INTERVAL) { + logger.error("Receive bad block {} from peer {}, block time error", + blockMessage.getBlockId(), peer.getInetSocketAddress()); + throw new P2pException(TypeEnum.BAD_MESSAGE, "block time error"); + } if (!fastForward && !peer.isRelayPeer()) { check(peer, blockMessage); } @@ -109,18 +121,6 @@ private void check(PeerConnection peer, BlockMessage msg) throws P2pException { msg.getBlockId(), peer.getInetSocketAddress()); throw new P2pException(TypeEnum.BAD_MESSAGE, "no request"); } - BlockCapsule blockCapsule = msg.getBlockCapsule(); - if (blockCapsule.getInstance().getSerializedSize() > maxBlockSize) { - logger.error("Receive bad block {} from peer {}, block size over limit", - msg.getBlockId(), peer.getInetSocketAddress()); - throw new P2pException(TypeEnum.BAD_MESSAGE, "block size over limit"); - } - long gap = blockCapsule.getTimeStamp() - System.currentTimeMillis(); - if (gap >= BLOCK_PRODUCED_INTERVAL) { - logger.error("Receive bad block {} from peer {}, block time error", - msg.getBlockId(), peer.getInetSocketAddress()); - throw new P2pException(TypeEnum.BAD_MESSAGE, "block time error"); - } } private void processBlock(PeerConnection peer, BlockCapsule block) throws P2pException { From 089fa8a76a8dac38413318b2efe31770933649c0 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Sun, 28 Apr 2024 16:59:27 +0800 Subject: [PATCH 4/8] fix(net): solve the problem of concurrent access to fetchBlockInfo object --- .../tron/core/net/service/fetchblock/FetchBlockService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/service/fetchblock/FetchBlockService.java b/framework/src/main/java/org/tron/core/net/service/fetchblock/FetchBlockService.java index 889f6f6e132..bda2646abbc 100644 --- a/framework/src/main/java/org/tron/core/net/service/fetchblock/FetchBlockService.java +++ b/framework/src/main/java/org/tron/core/net/service/fetchblock/FetchBlockService.java @@ -71,9 +71,10 @@ public void fetchBlock(List sha256HashList, PeerConnection peer) { sha256HashList.stream().filter(sha256Hash -> new BlockCapsule.BlockId(sha256Hash).getNum() == chainBaseManager.getHeadBlockNum() + 1) .findFirst().ifPresent(sha256Hash -> { - fetchBlockInfo = new FetchBlockInfo(sha256Hash, peer, System.currentTimeMillis()); + long now = System.currentTimeMillis(); + fetchBlockInfo = new FetchBlockInfo(sha256Hash, peer, now); logger.info("Set fetchBlockInfo, block: {}, peer: {}, time: {}", sha256Hash, - fetchBlockInfo.getPeer().getInetAddress(), fetchBlockInfo.getTime()); + peer.getInetAddress(), now); }); } From 9cc15de61a8db733852549de351d2ace645dbdcc Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Thu, 30 May 2024 10:23:53 +0800 Subject: [PATCH 5/8] feat(consensus): add unit test for DposTask --- .../org/tron/core/consensus/DposTaskTest.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 framework/src/test/java/org/tron/core/consensus/DposTaskTest.java diff --git a/framework/src/test/java/org/tron/core/consensus/DposTaskTest.java b/framework/src/test/java/org/tron/core/consensus/DposTaskTest.java new file mode 100644 index 00000000000..89d887d5fe9 --- /dev/null +++ b/framework/src/test/java/org/tron/core/consensus/DposTaskTest.java @@ -0,0 +1,64 @@ +package org.tron.core.consensus; + +import static org.mockito.Mockito.mock; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.tron.consensus.base.BlockHandle; +import org.tron.consensus.base.State; +import org.tron.consensus.dpos.DposService; +import org.tron.consensus.dpos.DposSlot; +import org.tron.consensus.dpos.DposTask; +import org.tron.consensus.dpos.StateManager; + +public class DposTaskTest { + private DposTask dposTask = new DposTask(); + + @Test + public void tet() throws Exception { + StateManager stateManager = mock(StateManager.class); + Mockito.when(stateManager.getState()).thenReturn(State.BACKUP_IS_NOT_MASTER); + + Field field = dposTask.getClass().getDeclaredField("stateManager"); + field.setAccessible(true); + field.set(dposTask, stateManager); + + Method method = dposTask.getClass().getDeclaredMethod("produceBlock"); + method.setAccessible(true); + State state = (State) method.invoke(dposTask); + + Assert.assertEquals(State.BACKUP_IS_NOT_MASTER, state); + + + Mockito.when(stateManager.getState()).thenReturn(State.OK); + + DposSlot dposSlot = mock(DposSlot.class); + Mockito.when(dposSlot.getTime(1)).thenReturn(Long.MAX_VALUE); + + field = dposTask.getClass().getDeclaredField("dposSlot"); + field.setAccessible(true); + field.set(dposTask, dposSlot); + + + Mockito.when(stateManager.getState()).thenReturn(State.OK); + + BlockHandle blockHandle = mock(BlockHandle.class); + Mockito.when(blockHandle.getLock()).thenReturn(new Object()); + + + DposService dposService = mock(DposService.class); + Mockito.when(dposService.getBlockHandle()).thenReturn(blockHandle); + + field = dposTask.getClass().getDeclaredField("dposService"); + field.setAccessible(true); + field.set(dposTask, dposService); + + state = (State) method.invoke(dposTask); + + Assert.assertEquals(State.NOT_TIME_YET, state); + } + +} From b311f9a6d0c4faf84eec61451c12b66432e684f2 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Thu, 30 May 2024 10:32:54 +0800 Subject: [PATCH 6/8] feat(net): remove redundant code --- .../org/tron/core/net/messagehandler/BlockMsgHandler.java | 7 ------- .../java/org/tron/core/net/service/adv/AdvService.java | 1 - 2 files changed, 8 deletions(-) diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java index 14523df86a5..66ebeaa641a 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/BlockMsgHandler.java @@ -150,14 +150,7 @@ private void processBlock(PeerConnection peer, BlockCapsule block) throws P2pExc try { tronNetDelegate.processBlock(block, false); - witnessProductBlockService.validWitnessProductTwoBlock(block); - - tronNetDelegate.getActivePeer().forEach(p -> { - if (p.getAdvInvReceive().getIfPresent(blockId) != null) { - p.setBlockBothHave(blockId); - } - }); } catch (Exception e) { logger.warn("Process adv block {} from peer {} failed. reason: {}", blockId, peer.getInetAddress(), e.getMessage()); diff --git a/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java b/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java index ea608c1ea86..505b53358c8 100644 --- a/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java +++ b/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java @@ -200,7 +200,6 @@ public void broadcast(Message msg) { logger.info("Ready to broadcast block {}", blockMsg.getBlockId().getString()); blockMsg.getBlockCapsule().getTransactions().forEach(transactionCapsule -> { Sha256Hash tid = transactionCapsule.getTransactionId(); - invToSpread.remove(tid); trxCache.put(new Item(tid, InventoryType.TRX), new TransactionMessage(transactionCapsule.getInstance())); }); From 9378787b8b8e2139ab3644d9bf335ec262a73836 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Thu, 30 May 2024 11:42:11 +0800 Subject: [PATCH 7/8] feat(version): update version to 4.7.5 --- framework/src/main/java/org/tron/program/Version.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/program/Version.java b/framework/src/main/java/org/tron/program/Version.java index 483f5be713f..ee624f6078a 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.3.1-78-ge84a9e778"; public static final String VERSION_CODE = "18260"; - private static final String VERSION = "4.7.4"; + private static final String VERSION = "4.7.5"; public static String getVersion() { return VERSION; From e434b28444934c7d39e1dd1f0d5b734b92f33cdc Mon Sep 17 00:00:00 2001 From: liuxincheng Date: Wed, 29 May 2024 22:53:27 +0800 Subject: [PATCH 8/8] feat(validate): validate account creation transaction size --- .../org/tron/core/utils/ProposalUtil.java | 19 ++++++- .../tron/core/capsule/TransactionCapsule.java | 3 ++ .../org/tron/core/db/BandwidthProcessor.java | 18 +++++-- .../org/tron/core/db/ResourceProcessor.java | 3 +- .../core/store/DynamicPropertiesStore.java | 14 ++++++ .../common/parameter/CommonParameter.java | 4 ++ .../src/main/java/org/tron/core/Constant.java | 3 ++ .../java/org/tron/core/config/Parameter.java | 5 +- .../src/main/java/org/tron/core/Wallet.java | 5 ++ .../tron/core/consensus/ProposalService.java | 4 ++ .../main/java/org/tron/core/db/Manager.java | 3 +- .../vm/BandWidthRuntimeOutOfTimeTest.java | 4 +- ...andWidthRuntimeOutOfTimeWithCheckTest.java | 4 +- .../runtime/vm/BandWidthRuntimeTest.java | 4 +- .../vm/BandWidthRuntimeWithCheckTest.java | 3 +- .../org/tron/core/BandwidthProcessorTest.java | 7 +++ .../actuator/ProposalCreateActuatorTest.java | 50 +++++++++++++++++++ .../org/tron/core/config/args/ArgsTest.java | 1 + 18 files changed, 142 insertions(+), 12 deletions(-) diff --git a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java index cfec5b09d96..c82ed0a8302 100644 --- a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java +++ b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java @@ -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; @@ -748,6 +750,20 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore, } 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; } @@ -824,7 +840,8 @@ 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 + MAX_CREATE_ACCOUNT_TX_SIZE(82); // [500, 10000] private long code; diff --git a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java index a588b28c748..f897e5d848a 100755 --- a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java @@ -114,6 +114,9 @@ public class TransactionCapsule implements ProtoCapsule { @Getter @Setter private boolean isTransactionCreate = false; + @Getter + @Setter + private boolean isInBlock = false; public byte[] getOwnerAddress() { if (this.ownerAddress == null) { diff --git a/chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java b/chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java index f13002f2dfa..d6da5904aa3 100644 --- a/chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java +++ b/chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java @@ -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; @@ -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 { @@ -95,7 +96,7 @@ public void updateUsage(AssetIssueCapsule assetIssueCapsule, long now) { @Override public void consume(TransactionCapsule trx, TransactionTrace trace) throws ContractValidateException, AccountResourceInsufficientException, - TooBigTransactionResultException { + TooBigTransactionResultException, TooBigTransactionException { List contracts = trx.getInstance().getRawData().getContractList(); if (trx.getResultSerializedSize() > Constant.MAX_RESULT_SIZE_IN_TX * contracts.size()) { throw new TooBigTransactionResultException(); @@ -127,6 +128,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; } diff --git a/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java b/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java index a7a22390958..c1875408850 100644 --- a/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java +++ b/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java @@ -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; @@ -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); diff --git a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java index bf788232640..57a21753b9a 100644 --- a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java +++ b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java @@ -219,6 +219,8 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking private static final byte[] ALLOW_OLD_REWARD_OPT = "ALLOW_OLD_REWARD_OPT".getBytes(); + private static final byte[] MAX_CREATE_ACCOUNT_TX_SIZE = "MAX_CREATE_ACCOUNT_TX_SIZE".getBytes(); + @Autowired private DynamicPropertiesStore(@Value("properties") String dbName) { super(dbName); @@ -2850,6 +2852,18 @@ public long getAllowOldRewardOpt() { .orElse(CommonParameter.getInstance().getAllowOldRewardOpt()); } + public void saveMaxCreateAccountTxSize(long maxCreateAccountTxSize) { + this.put(MAX_CREATE_ACCOUNT_TX_SIZE, + new BytesCapsule(ByteArray.fromLong(maxCreateAccountTxSize))); + } + + public long getMaxCreateAccountTxSize() { + return Optional.ofNullable(getUnchecked(MAX_CREATE_ACCOUNT_TX_SIZE)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElse(CommonParameter.getInstance().getMaxCreateAccountTxSize()); + } + private static class DynamicResourceProperties { private static final byte[] ONE_DAY_NET_LIMIT = "ONE_DAY_NET_LIMIT".getBytes(); diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index f9562e580e3..d511f6b0d49 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -666,6 +666,10 @@ public class CommonParameter { @Setter public long allowOldRewardOpt; + @Getter + @Setter + public long maxCreateAccountTxSize = 1000L; + private static double calcMaxTimeRatio() { //return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1))); return 5.0; diff --git a/common/src/main/java/org/tron/core/Constant.java b/common/src/main/java/org/tron/core/Constant.java index 2cd9ea95f15..729f59c8317 100644 --- a/common/src/main/java/org/tron/core/Constant.java +++ b/common/src/main/java/org/tron/core/Constant.java @@ -24,6 +24,8 @@ public class Constant { // config for transaction public static final long TRANSACTION_MAX_BYTE_SIZE = 500 * 1_024L; + public static final int CREATE_ACCOUNT_TRANSACTION_MIN_BYTE_SIZE = 500; + public static final int CREATE_ACCOUNT_TRANSACTION_MAX_BYTE_SIZE = 10000; public static final long MAXIMUM_TIME_UNTIL_EXPIRATION = 24 * 60 * 60 * 1_000L; //one day public static final long TRANSACTION_DEFAULT_EXPIRATION_TIME = 60 * 1_000L; //60 seconds public static final long TRANSACTION_FEE_POOL_PERIOD = 1; //1 blocks @@ -31,6 +33,7 @@ public class Constant { public static final long SUN_PER_ENERGY = 100; // 1 us = 100 SUN = 100 * 10^-6 TRX public static final long ENERGY_LIMIT_IN_CONSTANT_TX = 3_000_000L; // ref: 1 us = 1 energy public static final long MAX_RESULT_SIZE_IN_TX = 64; // max 8 * 8 items in result + public static final long PER_SIGN_LENGTH = 65L; public static final long PB_DEFAULT_ENERGY_LIMIT = 0L; public static final long CREATOR_DEFAULT_ENERGY_LIMIT = 1000 * 10_000L; 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 247826af77a..027c225eb5d 100644 --- a/common/src/main/java/org/tron/core/config/Parameter.java +++ b/common/src/main/java/org/tron/core/config/Parameter.java @@ -23,7 +23,8 @@ public enum ForkBlockVersionEnum { VERSION_4_7(26, 1596780000000L, 80), VERSION_4_7_1(27, 1596780000000L, 80), VERSION_4_7_2(28, 1596780000000L, 80), - VERSION_4_7_4(29, 1596780000000L, 80); + VERSION_4_7_4(29, 1596780000000L, 80), + VERSION_4_7_5(30, 1596780000000L, 80); // if add a version, modify BLOCK_VERSION simultaneously @Getter @@ -72,7 +73,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 = 29; + public static final int BLOCK_VERSION = 30; 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/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 96af6fc7476..50dffcf3c83 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -1334,6 +1334,11 @@ public Protocol.ChainParameters getChainParameters() { .setValue(dbManager.getDynamicPropertiesStore().getAllowOldRewardOpt()) .build()); + builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder() + .setKey("getMaxCreateAccountTxSize") + .setValue(dbManager.getDynamicPropertiesStore().getMaxCreateAccountTxSize()) + .build()); + return builder.build(); } diff --git a/framework/src/main/java/org/tron/core/consensus/ProposalService.java b/framework/src/main/java/org/tron/core/consensus/ProposalService.java index 58da117cfc6..73628c6e2b9 100644 --- a/framework/src/main/java/org/tron/core/consensus/ProposalService.java +++ b/framework/src/main/java/org/tron/core/consensus/ProposalService.java @@ -359,6 +359,10 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule) manager.getDynamicPropertiesStore().saveAllowOldRewardOpt(entry.getValue()); break; } + case MAX_CREATE_ACCOUNT_TX_SIZE: { + manager.getDynamicPropertiesStore().saveMaxCreateAccountTxSize(entry.getValue()); + break; + } default: find = false; break; 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 63bbef9ff7f..69265951ea8 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -966,7 +966,7 @@ public void consumeMemoFee(TransactionCapsule trx, TransactionTrace trace) public void consumeBandwidth(TransactionCapsule trx, TransactionTrace trace) throws ContractValidateException, AccountResourceInsufficientException, - TooBigTransactionResultException { + TooBigTransactionResultException, TooBigTransactionException { BandwidthProcessor processor = new BandwidthProcessor(chainBaseManager); processor.consume(trx, trace); } @@ -1422,6 +1422,7 @@ public TransactionInfo processTransaction(final TransactionCapsule trxCap, Block if (Objects.nonNull(blockCap)) { chainBaseManager.getBalanceTraceStore().initCurrentTransactionBalanceTrace(trxCap); + trxCap.setInBlock(true); } validateTapos(trxCap); diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeTest.java index afac8cd7d22..30bba35b43c 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeTest.java @@ -33,6 +33,7 @@ import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.TooBigTransactionException; import org.tron.core.exception.TooBigTransactionResultException; import org.tron.core.exception.TronException; import org.tron.core.exception.VMIllegalException; @@ -154,7 +155,8 @@ public void testSuccess() { private byte[] createContract() throws ContractValidateException, AccountResourceInsufficientException, - TooBigTransactionResultException, ContractExeException, VMIllegalException { + TooBigTransactionResultException, ContractExeException, VMIllegalException, + TooBigTransactionException { AccountCapsule owner = dbManager.getAccountStore() .get(Commons.decodeFromBase58Check(OwnerAddress)); long energy = owner.getEnergyUsage(); diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeWithCheckTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeWithCheckTest.java index 7203388f815..0eef2266f9d 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeWithCheckTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeWithCheckTest.java @@ -34,6 +34,7 @@ import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ReceiptCheckErrException; +import org.tron.core.exception.TooBigTransactionException; import org.tron.core.exception.TooBigTransactionResultException; import org.tron.core.exception.TronException; import org.tron.core.exception.VMIllegalException; @@ -156,7 +157,8 @@ public void testSuccess() { private byte[] createContract() throws ContractValidateException, AccountResourceInsufficientException, - TooBigTransactionResultException, ContractExeException, VMIllegalException { + TooBigTransactionResultException, ContractExeException, VMIllegalException, + TooBigTransactionException { AccountCapsule owner = dbManager.getAccountStore() .get(Commons.decodeFromBase58Check(OwnerAddress)); long energy = owner.getEnergyUsage(); diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeTest.java index 40c5908c2dd..8b8e3a3c1eb 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeTest.java @@ -35,6 +35,7 @@ import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.TooBigTransactionException; import org.tron.core.exception.TooBigTransactionResultException; import org.tron.core.exception.TronException; import org.tron.core.exception.VMIllegalException; @@ -186,7 +187,8 @@ public void testSuccessNoBandd() { private byte[] createContract() throws ContractValidateException, AccountResourceInsufficientException, - TooBigTransactionResultException, ContractExeException, VMIllegalException { + TooBigTransactionResultException, ContractExeException, VMIllegalException, + TooBigTransactionException { AccountCapsule owner = dbManager.getAccountStore() .get(Commons.decodeFromBase58Check(OwnerAddress)); long energy = owner.getEnergyUsage(); diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeWithCheckTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeWithCheckTest.java index e359e7eab1a..4b3331187e2 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeWithCheckTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeWithCheckTest.java @@ -34,6 +34,7 @@ import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ReceiptCheckErrException; +import org.tron.core.exception.TooBigTransactionException; import org.tron.core.exception.TooBigTransactionResultException; import org.tron.core.exception.TronException; import org.tron.core.exception.VMIllegalException; @@ -198,7 +199,7 @@ public void testSuccessNoBandWidth() { private byte[] createContract() throws ContractValidateException, AccountResourceInsufficientException, TooBigTransactionResultException, ContractExeException, ReceiptCheckErrException, - VMIllegalException { + VMIllegalException, TooBigTransactionException { AccountCapsule owner = dbManager.getAccountStore() .get(Commons.decodeFromBase58Check(OwnerAddress)); long energy = owner.getEnergyUsage(); diff --git a/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java b/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java index 300c202e11a..7d13892c635 100755 --- a/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java +++ b/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java @@ -19,6 +19,7 @@ import org.tron.core.db.TransactionTrace; 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.core.store.StoreFactory; import org.tron.protos.Protocol; @@ -646,6 +647,8 @@ public void sameTokenNameCloseConsumeSuccess() { Assert.assertFalse(e instanceof TooBigTransactionResultException); } catch (AccountResourceInsufficientException e) { Assert.assertFalse(e instanceof AccountResourceInsufficientException); + } catch (TooBigTransactionException e) { + Assert.fail(); } finally { chainBaseManager.getAccountStore().delete(ByteArray.fromHexString(OWNER_ADDRESS)); chainBaseManager.getAccountStore().delete(ByteArray.fromHexString(TO_ADDRESS)); @@ -752,6 +755,8 @@ public void sameTokenNameOpenConsumeSuccess() { Assert.assertFalse(e instanceof TooBigTransactionResultException); } catch (AccountResourceInsufficientException e) { Assert.assertFalse(e instanceof AccountResourceInsufficientException); + } catch (TooBigTransactionException e) { + Assert.fail(); } finally { chainBaseManager.getAccountStore().delete(ByteArray.fromHexString(OWNER_ADDRESS)); chainBaseManager.getAccountStore().delete(ByteArray.fromHexString(TO_ADDRESS)); @@ -821,6 +826,8 @@ public void sameTokenNameCloseTransferToAccountNotExist() { Assert.assertFalse(e instanceof TooBigTransactionResultException); } catch (AccountResourceInsufficientException e) { Assert.assertFalse(e instanceof AccountResourceInsufficientException); + } catch (TooBigTransactionException e) { + Assert.fail(); } finally { chainBaseManager.getAccountStore().delete(ByteArray.fromHexString(OWNER_ADDRESS)); chainBaseManager.getAccountStore().delete(ByteArray.fromHexString(TO_ADDRESS)); diff --git a/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java index a42a4ffbe5a..7210fe8d074 100644 --- a/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java @@ -1,6 +1,10 @@ package org.tron.core.actuator; import static junit.framework.TestCase.fail; +import static org.junit.Assert.assertThrows; +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.config.Parameter.ChainConstant.ONE_YEAR_BLOCK_NUMBERS; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -9,8 +13,10 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.ForkController; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -279,6 +285,50 @@ public void invalidPara() { Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", e.getMessage()); } + // verify Proposal No. 78 + paras = new HashMap<>(); + paras.put(78L, 10L); + actuator = new ProposalCreateActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()) + .setForkUtils(dbManager.getChainBaseManager().getForkController()) + .setAny(getContract(OWNER_ADDRESS_FIRST, paras)); + assertThrows( + "Bad chain parameter id [MAX_DELEGATE_LOCK_PERIOD]", + ContractValidateException.class, actuator::validate); + + actuator = new ProposalCreateActuator(); + ForkController forkController = Mockito.mock(ForkController.class); + Mockito.when(forkController.pass(Mockito.any())).thenReturn(true); + actuator.setChainBaseManager(dbManager.getChainBaseManager()) + .setForkUtils(forkController) + .setAny(getContract(OWNER_ADDRESS_FIRST, paras)); + dbManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(86400L); + long maxDelegateLockPeriod = dbManager.getDynamicPropertiesStore().getMaxDelegateLockPeriod(); + assertThrows( + "This value[MAX_DELEGATE_LOCK_PERIOD] is only allowed to be greater than " + + maxDelegateLockPeriod + " and less than or equal to " + ONE_YEAR_BLOCK_NUMBERS + "!", + ContractValidateException.class, actuator::validate); + + // verify Proposal No. 82 + paras = new HashMap<>(); + paras.put(82L, 0L); + actuator = new ProposalCreateActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()) + .setForkUtils(dbManager.getChainBaseManager().getForkController()) + .setAny(getContract(OWNER_ADDRESS_FIRST, paras)); + assertThrows( + "Bad chain parameter id [ALLOW_ENERGY_ADJUSTMENT]", + ContractValidateException.class, actuator::validate); + + actuator = new ProposalCreateActuator(); + actuator.setChainBaseManager(dbManager.getChainBaseManager()) + .setForkUtils(forkController) + .setAny(getContract(OWNER_ADDRESS_FIRST, paras)); + assertThrows( + "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 + "!", + ContractValidateException.class, actuator::validate); } /** diff --git a/framework/src/test/java/org/tron/core/config/args/ArgsTest.java b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java index 52307d9d294..5bbf08fd96e 100644 --- a/framework/src/test/java/org/tron/core/config/args/ArgsTest.java +++ b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java @@ -101,6 +101,7 @@ public void get() { Assert.assertEquals(43, parameter.getNodeP2pVersion()); Assert.assertEquals(54, parameter.getMaxUnsolidifiedBlocks()); Assert.assertEquals(false, parameter.isUnsolidifiedBlockCheck()); + Assert.assertEquals(1000, parameter.getMaxCreateAccountTxSize()); //Assert.assertEquals(30, args.getSyncNodeCount()); // gRPC network configs checking