diff --git a/src/main/java/org/tron/core/Constant.java b/src/main/java/org/tron/core/Constant.java index 1574749e51a..1aaf8aac629 100644 --- a/src/main/java/org/tron/core/Constant.java +++ b/src/main/java/org/tron/core/Constant.java @@ -52,6 +52,7 @@ public class Constant { public static final long STORAGE_LIMIT_IN_ONE_TX_OF_SMART_CONTRACT = 32 * 1024 * 1024L; // 32MB public static final long SUN_PER_ENERGY = 100; // 1 us = 100 DROP = 100 * 10^-6 TRX public static final long MAX_ENERGY_IN_TX = 3000000; // 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 MAX_CONSUME_USER_RESOURCE_PERCENT = 100L; public static final long MIN_CONSUME_USER_RESOURCE_PERCENT = 0L; public static final long ACCORD_RANGE_PERCENT = 0L; diff --git a/src/main/java/org/tron/core/Wallet.java b/src/main/java/org/tron/core/Wallet.java index 0e29294cfda..84aa6b48540 100755 --- a/src/main/java/org/tron/core/Wallet.java +++ b/src/main/java/org/tron/core/Wallet.java @@ -407,7 +407,9 @@ public GrpcAPI.Return broadcastTransaction(Transaction signaturedTransaction) { } else { dbManager.getTransactionIdCache().put(trx.getTransactionId(), true); } - + if (dbManager.getDynamicPropertiesStore().supportVM()) { + trx.resetResult(); + } dbManager.pushTransaction(trx); p2pNode.broadcast(message); diff --git a/src/main/java/org/tron/core/capsule/TransactionCapsule.java b/src/main/java/org/tron/core/capsule/TransactionCapsule.java index cd7fb7857bf..0df97dd2900 100755 --- a/src/main/java/org/tron/core/capsule/TransactionCapsule.java +++ b/src/main/java/org/tron/core/capsule/TransactionCapsule.java @@ -485,6 +485,14 @@ public long getSerializedSize() { return this.transaction.getSerializedSize(); } + public long getResultSerializedSize() { + long size = 0; + for (Result result : this.transaction.getRetList()) { + size += result.getSerializedSize(); + } + return size; + } + @Override public Transaction getInstance() { return this.transaction; diff --git a/src/main/java/org/tron/core/db/BandwidthProcessor.java b/src/main/java/org/tron/core/db/BandwidthProcessor.java index fcda5c23e4c..530cf7e89c9 100644 --- a/src/main/java/org/tron/core/db/BandwidthProcessor.java +++ b/src/main/java/org/tron/core/db/BandwidthProcessor.java @@ -8,12 +8,14 @@ import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.TransactionResultCapsule; import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.TooBigTransactionResultException; import org.tron.protos.Contract.TransferAssetContract; import org.tron.protos.Contract.TransferContract; import org.tron.protos.Protocol.Transaction.Contract; @@ -50,13 +52,21 @@ private void updateUsage(AccountCapsule accountCapsule, long now) { @Override public void consume(TransactionCapsule trx, TransactionResultCapsule ret, TransactionTrace trace) - throws ContractValidateException, AccountResourceInsufficientException { - List contracts = - trx.getInstance().getRawData().getContractList(); - TransactionCapsule transactionCapsule = new TransactionCapsule(trx.getInstance().getRawData(), - trx.getInstance().getSignatureList()); + throws ContractValidateException, AccountResourceInsufficientException, TooBigTransactionResultException { + List contracts = trx.getInstance().getRawData().getContractList(); + if (trx.getResultSerializedSize() > Constant.MAX_RESULT_SIZE_IN_TX * contracts.size()) { + throw new TooBigTransactionResultException(); + } for (Contract contract : contracts) { - long bytes = transactionCapsule.getSerializedSize(); + long bytes = 0; + if (dbManager.getDynamicPropertiesStore().supportVM()) { + TransactionCapsule txCapForEstimateBandWidth = new TransactionCapsule( + trx.getInstance().getRawData(), + trx.getInstance().getSignatureList()); + bytes = txCapForEstimateBandWidth.getSerializedSize() + Constant.MAX_RESULT_SIZE_IN_TX; + } else { + bytes = trx.getSerializedSize(); + } logger.debug("trxId {},bandwidth cost :{}", trx.getTransactionId(), bytes); trace.setNetBill(bytes, 0); byte[] address = TransactionCapsule.getOwner(contract); diff --git a/src/main/java/org/tron/core/db/Manager.java b/src/main/java/org/tron/core/db/Manager.java index 65f17974f5d..2de950f823c 100644 --- a/src/main/java/org/tron/core/db/Manager.java +++ b/src/main/java/org/tron/core/db/Manager.java @@ -39,7 +39,6 @@ import org.springframework.stereotype.Component; import org.tron.common.overlay.discover.node.Node; import org.tron.common.runtime.Runtime; -import org.tron.common.runtime.config.SystemProperties; import org.tron.common.runtime.vm.program.invoke.ProgramInvokeFactoryImpl; import org.tron.common.storage.DepositImpl; import org.tron.common.utils.ByteArray; @@ -82,6 +81,7 @@ import org.tron.core.exception.ReceiptException; import org.tron.core.exception.TaposException; import org.tron.core.exception.TooBigTransactionException; +import org.tron.core.exception.TooBigTransactionResultException; import org.tron.core.exception.TransactionExpirationException; import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.UnLinkedBlockException; @@ -585,7 +585,7 @@ public boolean pushTransaction(final TransactionCapsule trx) throws ValidateSignatureException, ContractValidateException, ContractExeException, AccountResourceInsufficientException, DupTransactionException, TaposException, TooBigTransactionException, TransactionExpirationException, ReceiptException, - TransactionTraceException, ReceiptCheckErrException, UnsupportVMException { + TransactionTraceException, ReceiptCheckErrException, UnsupportVMException, TooBigTransactionResultException { if (!trx.validateSignature()) { throw new ValidateSignatureException("trans sig validate failed"); @@ -609,7 +609,7 @@ public boolean pushTransaction(final TransactionCapsule trx) public void consumeBandwidth(TransactionCapsule trx, TransactionResultCapsule ret, TransactionTrace trace) - throws ContractValidateException, AccountResourceInsufficientException { + throws ContractValidateException, AccountResourceInsufficientException, TooBigTransactionResultException { BandwidthProcessor processor = new BandwidthProcessor(this); processor.consume(trx, ret, trace); } @@ -680,7 +680,7 @@ private void applyBlock(BlockCapsule block) throws ContractValidateException, ContractExeException, ValidateSignatureException, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, DupTransactionException, ReceiptException, TaposException, ValidateScheduleException, TransactionTraceException, ReceiptCheckErrException, - UnsupportVMException { + UnsupportVMException, TooBigTransactionResultException { processBlock(block); this.blockStore.put(block.getBlockId().getBytes(), block); this.blockIndexStore.put(block.getBlockId()); @@ -690,7 +690,7 @@ private void applyBlock(BlockCapsule block) throws ContractValidateException, private void switchFork(BlockCapsule newHead) throws ValidateSignatureException, ContractValidateException, ContractExeException, ValidateScheduleException, AccountResourceInsufficientException, TaposException, - TooBigTransactionException, DupTransactionException, TransactionExpirationException, + TooBigTransactionException, TooBigTransactionResultException, DupTransactionException, TransactionExpirationException, NonCommonBlockException, ReceiptException, TransactionTraceException, ReceiptCheckErrException, UnsupportVMException { Pair, LinkedList> binaryTree; @@ -737,6 +737,7 @@ private void switchFork(BlockCapsule newHead) | ReceiptException | ReceiptCheckErrException | TooBigTransactionException + | TooBigTransactionResultException | ValidateScheduleException | UnsupportVMException e) { logger.warn(e.getMessage(), e); @@ -792,7 +793,7 @@ private synchronized void filterPendingTrx(List listTrx) { public synchronized void pushBlock(final BlockCapsule block) throws ValidateSignatureException, ContractValidateException, ContractExeException, UnLinkedBlockException, ValidateScheduleException, AccountResourceInsufficientException, - TaposException, TooBigTransactionException, DupTransactionException, TransactionExpirationException, + TaposException, TooBigTransactionException, TooBigTransactionResultException, DupTransactionException, TransactionExpirationException, BadNumberBlockException, BadBlockException, NonCommonBlockException, ReceiptException, TransactionTraceException, ReceiptCheckErrException, UnsupportVMException { try (PendingManager pm = new PendingManager(this)) { @@ -1006,7 +1007,7 @@ public boolean hasBlocks() { */ public boolean processTransaction(final TransactionCapsule trxCap, BlockCapsule blockCap) throws ValidateSignatureException, ContractValidateException, ContractExeException, ReceiptException, - AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, + AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, TooBigTransactionResultException, DupTransactionException, TaposException, TransactionTraceException, ReceiptCheckErrException, UnsupportVMException { if (trxCap == null) { return false; @@ -1040,7 +1041,7 @@ public boolean processTransaction(final TransactionCapsule trxCap, BlockCapsule // Fixme Wrong exception throw new UnsupportVMException("cannot call constant method "); } - // if (SystemProperties.getInstance().vmOn()) { + // if (getDynamicPropertiesStore().supportVM()) { // if(trxCap.getInstance().getRetCount()<=0){ // trxCap.setResult(new TransactionResultCapsule(contractResult.UNKNOWN)); // } @@ -1068,7 +1069,7 @@ public boolean processTransaction(final TransactionCapsule trxCap, BlockCapsule trace.finalization(runtime); if (Objects.nonNull(blockCap)) { - if (SystemProperties.getInstance().vmOn()) { + if (getDynamicPropertiesStore().supportVM()) { trxCap.setResult(runtime); } } @@ -1159,6 +1160,9 @@ public synchronized BlockCapsule generateBlock( } catch (TooBigTransactionException e) { logger.info("contract not processed during TooBigTransactionException"); logger.debug(e.getMessage(), e); + } catch (TooBigTransactionResultException e) { + logger.info("contract not processed during TooBigTransactionResultException"); + logger.debug(e.getMessage(), e); } catch (TransactionExpirationException e) { logger.info("contract not processed during TransactionExpirationException"); logger.debug(e.getMessage(), e); @@ -1216,6 +1220,8 @@ public synchronized BlockCapsule generateBlock( logger.debug(e.getMessage(), e); } catch (UnsupportVMException e) { logger.warn(e.getMessage(), e); + } catch (TooBigTransactionResultException e) { + logger.info("contract not processed during TooBigTransactionResultException"); } return null; @@ -1256,7 +1262,7 @@ public void processBlock(BlockCapsule block) throws ValidateSignatureException, ContractValidateException, ContractExeException, AccountResourceInsufficientException, TaposException, TooBigTransactionException, DupTransactionException, TransactionExpirationException, ValidateScheduleException, - ReceiptException, TransactionTraceException, ReceiptCheckErrException, UnsupportVMException { + ReceiptException, TransactionTraceException, ReceiptCheckErrException, UnsupportVMException, TooBigTransactionResultException { // todo set revoking db max size. // checkWitness @@ -1582,6 +1588,8 @@ public void rePush(TransactionCapsule tx) { logger.debug("outOfSlotTime transaction"); } catch (UnsupportVMException e) { logger.debug(e.getMessage(), e); + } catch (TooBigTransactionResultException e) { + logger.debug("too big transaction result"); } } } diff --git a/src/main/java/org/tron/core/db/ResourceProcessor.java b/src/main/java/org/tron/core/db/ResourceProcessor.java index 2e62e445dba..356aa505d11 100644 --- a/src/main/java/org/tron/core/db/ResourceProcessor.java +++ b/src/main/java/org/tron/core/db/ResourceProcessor.java @@ -7,6 +7,7 @@ import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.BalanceInsufficientException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.TooBigTransactionResultException; abstract class ResourceProcessor { @@ -24,7 +25,7 @@ public ResourceProcessor(Manager manager) { abstract void consume(TransactionCapsule trx, TransactionResultCapsule ret, TransactionTrace trace) - throws ContractValidateException, AccountResourceInsufficientException; + throws ContractValidateException, AccountResourceInsufficientException, TooBigTransactionResultException; protected long increase(long lastUsage, long usage, long lastTime, long now) { long averageLastUsage = divideCeil(lastUsage * precision, windowSize); diff --git a/src/main/java/org/tron/core/exception/TooBigTransactionResultException.java b/src/main/java/org/tron/core/exception/TooBigTransactionResultException.java new file mode 100644 index 00000000000..ecb9978c31b --- /dev/null +++ b/src/main/java/org/tron/core/exception/TooBigTransactionResultException.java @@ -0,0 +1,8 @@ +package org.tron.core.exception; + +public class TooBigTransactionResultException extends TronException { + + public TooBigTransactionResultException() { super("too big transaction result"); } + + public TooBigTransactionResultException(String message) { super(message); } +} diff --git a/src/main/java/org/tron/core/net/message/TransactionMessage.java b/src/main/java/org/tron/core/net/message/TransactionMessage.java index 8a9a3aa222c..cc037398328 100644 --- a/src/main/java/org/tron/core/net/message/TransactionMessage.java +++ b/src/main/java/org/tron/core/net/message/TransactionMessage.java @@ -1,5 +1,6 @@ package org.tron.core.net.message; +import org.tron.common.runtime.config.SystemProperties; import org.tron.common.utils.Sha256Hash; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.exception.BadItemException; @@ -38,7 +39,6 @@ public Class getAnswerMessage() { } public TransactionCapsule getTransactionCapsule() { - //this.transactionCapsule.resetResult(); return this.transactionCapsule; } } diff --git a/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java b/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java index 5d567998bcd..8cb05735e42 100755 --- a/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java +++ b/src/main/java/org/tron/core/net/node/NodeDelegateImpl.java @@ -35,6 +35,7 @@ import org.tron.core.exception.StoreException; import org.tron.core.exception.TaposException; import org.tron.core.exception.TooBigTransactionException; +import org.tron.core.exception.TooBigTransactionResultException; import org.tron.core.exception.TransactionExpirationException; import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.TronException; @@ -97,6 +98,8 @@ public synchronized LinkedList handleBlock(BlockCapsule block, boole throw new BadBlockException("DupTransaction exception," + e.getMessage()); } catch (TooBigTransactionException e) { throw new BadBlockException("TooBigTransaction exception," + e.getMessage()); + } catch (TooBigTransactionResultException e) { + throw new BadBlockException("TooBigTransaction exception," + e.getMessage()); } catch (TransactionExpirationException e) { throw new BadBlockException("Expiration exception," + e.getMessage()); } catch (ReceiptException e) { @@ -116,6 +119,9 @@ public synchronized LinkedList handleBlock(BlockCapsule block, boole @Override public boolean handleTransaction(TransactionCapsule trx) throws BadTransactionException { + if (dbManager.getDynamicPropertiesStore().supportVM()) { + trx.resetResult(); + } logger.debug("handle transaction"); if (dbManager.getTransactionIdCache().getIfPresent(trx.getTransactionId()) != null) { logger.warn("This transaction has been processed"); @@ -165,6 +171,9 @@ public boolean handleTransaction(TransactionCapsule trx) throws BadTransactionEx } catch (UnsupportVMException e) { logger.warn(e.getMessage()); return false; + } catch (TooBigTransactionResultException e) { + logger.info("too big transactionresult" + e.getMessage()); + return false; } return true; diff --git a/src/main/java/org/tron/core/net/node/NodeImpl.java b/src/main/java/org/tron/core/net/node/NodeImpl.java index 65d5032e51e..612757fe270 100644 --- a/src/main/java/org/tron/core/net/node/NodeImpl.java +++ b/src/main/java/org/tron/core/net/node/NodeImpl.java @@ -46,6 +46,7 @@ import org.tron.common.utils.Time; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; +import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.Parameter.ChainConstant; import org.tron.core.config.Parameter.NetConstants; import org.tron.core.config.Parameter.NodeConstant; @@ -516,8 +517,8 @@ private void consumerAdvObjToSpread() { spread.putAll(advObjToSpread); advObjToSpread.clear(); } - for (InventoryType type : spread.values()){ - if (type == InventoryType.TRX){ + for (InventoryType type : spread.values()) { + if (type == InventoryType.TRX) { trxCount.add(); } } @@ -771,7 +772,8 @@ private void processAdvBlock(PeerConnection peer, BlockCapsule block) { del.getHeadBlockId().getString()); startSyncWithPeer(peer); } catch (NonCommonBlockException e) { - logger.error("We get a block {} that do not have the most recent common ancestor with the main chain, from {}, reason is {} ", + logger.error( + "We get a block {} that do not have the most recent common ancestor with the main chain, from {}, reason is {} ", block.getBlockId().getString(), peer.getNode().getHost(), e.getMessage()); disconnectPeer(peer, ReasonCode.FORKED); } catch (InterruptedException e) { @@ -805,7 +807,8 @@ private boolean processSyncBlock(BlockCapsule block) { del.getHeadBlockId().getString()); reason = ReasonCode.UNLINKABLE; } catch (NonCommonBlockException e) { - logger.error("We get a block {} that do not have the most recent common ancestor with the main chain, head is {}", + logger.error( + "We get a block {} that do not have the most recent common ancestor with the main chain, head is {}", block.getBlockId().getString(), del.getHeadBlockId().getString()); reason = ReasonCode.FORKED; @@ -857,7 +860,9 @@ private void onHandleTransactionMessage(PeerConnection peer, TransactionMessage peer.getNode().getHost()); return; } - if (del.handleTransaction(trxMsg.getTransactionCapsule())) { + TransactionCapsule transactionCapsule = trxMsg.getTransactionCapsule(); + + if (del.handleTransaction(transactionCapsule)) { broadcast(trxMsg); } } catch (TraitorPeerException e) { @@ -875,11 +880,12 @@ private void onHandleTransactionsMessage(PeerConnection peer, TransactionsMessag } } - private boolean checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage syncMsg){ + private boolean checkSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMessage syncMsg) { long lastBlockNum = syncMsg.getBlockIds().get(syncMsg.getBlockIds().size() - 1).getNum(); BlockId lastSyncBlockId = peer.getLastSyncBlockId(); - if (lastSyncBlockId != null && lastBlockNum < lastSyncBlockId.getNum()){ - logger.warn("Peer {} receive bad SyncBlockChain message, firstNum {} lastSyncNum {}.", peer.getInetAddress(), lastBlockNum, lastSyncBlockId.getNum()); + if (lastSyncBlockId != null && lastBlockNum < lastSyncBlockId.getNum()) { + logger.warn("Peer {} receive bad SyncBlockChain message, firstNum {} lastSyncNum {}.", + peer.getInetAddress(), lastBlockNum, lastSyncBlockId.getNum()); return false; } return true; @@ -891,7 +897,7 @@ private void onHandleSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMe long remainNum = 0; LinkedList blockIds = new LinkedList<>(); List summaryChainIds = syncMsg.getBlockIds(); - if (!checkSyncBlockChainMessage(peer, syncMsg)){ + if (!checkSyncBlockChainMessage(peer, syncMsg)) { disconnectPeer(peer, ReasonCode.BAD_PROTOCOL); return; } @@ -900,7 +906,7 @@ private void onHandleSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMe } catch (StoreException e) { logger.error(e.getMessage()); } - + if (blockIds.isEmpty()) { if (CollectionUtils.isNotEmpty(summaryChainIds) && !del .canChainRevoke(summaryChainIds.get(0).getNum())) { @@ -929,62 +935,71 @@ private void onHandleSyncBlockChainMessage(PeerConnection peer, SyncBlockChainMe startSyncWithPeer(peer); } - if (blockIds.peekLast() == null){ + if (blockIds.peekLast() == null) { peer.setLastSyncBlockId(headBlockId); - }else { + } else { peer.setLastSyncBlockId(blockIds.peekLast()); } peer.setRemainNum(remainNum); peer.sendMessage(new ChainInventoryMessage(blockIds, remainNum)); } - private boolean checkFetchInvDataMsg(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg){ + private boolean checkFetchInvDataMsg(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) { MessageTypes type = fetchInvDataMsg.getInvMessageType(); if (type == MessageTypes.TRX) { - int elementCount = peer.getNodeStatistics().messageStatistics.tronInTrxFetchInvDataElement.getCount(10); + int elementCount = peer.getNodeStatistics().messageStatistics.tronInTrxFetchInvDataElement + .getCount(10); int maxCount = trxCount.getCount(60); - if (elementCount > maxCount){ - logger.warn("Check FetchInvDataMsg failed: Peer {} request count {} in 10s gt trx count {} generate in 60s", peer.getInetAddress(), elementCount, maxCount); + if (elementCount > maxCount) { + logger.warn( + "Check FetchInvDataMsg failed: Peer {} request count {} in 10s gt trx count {} generate in 60s", + peer.getInetAddress(), elementCount, maxCount); return false; } for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (!peer.getAdvObjWeSpread().containsKey(hash)){ - logger.warn("Check FetchInvDataMsg failed: Peer {} get trx {} we not spread.", peer.getInetAddress(), hash); + if (!peer.getAdvObjWeSpread().containsKey(hash)) { + logger.warn("Check FetchInvDataMsg failed: Peer {} get trx {} we not spread.", + peer.getInetAddress(), hash); return false; } } - }else { + } else { boolean isAdv = true; for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { - if (!peer.getAdvObjWeSpread().containsKey(hash)){ + if (!peer.getAdvObjWeSpread().containsKey(hash)) { isAdv = false; break; } } - if (isAdv){ + if (isAdv) { MessageCount tronOutAdvBlock = peer.getNodeStatistics().messageStatistics.tronOutAdvBlock; tronOutAdvBlock.add(fetchInvDataMsg.getHashList().size()); int outBlockCountIn1min = tronOutAdvBlock.getCount(60); int producedBlockIn2min = 120_000 / ChainConstant.BLOCK_PRODUCED_INTERVAL; - if (outBlockCountIn1min > producedBlockIn2min){ - logger.warn("Check FetchInvDataMsg failed: Peer {} outBlockCount {} producedBlockIn2min {}", - peer.getInetAddress(), outBlockCountIn1min, producedBlockIn2min); + if (outBlockCountIn1min > producedBlockIn2min) { + logger + .warn("Check FetchInvDataMsg failed: Peer {} outBlockCount {} producedBlockIn2min {}", + peer.getInetAddress(), outBlockCountIn1min, producedBlockIn2min); return false; } - }else { - if (!peer.isNeedSyncFromUs()){ - logger.warn("Check FetchInvDataMsg failed: Peer {} not need sync from us.", peer.getInetAddress()); + } else { + if (!peer.isNeedSyncFromUs()) { + logger.warn("Check FetchInvDataMsg failed: Peer {} not need sync from us.", + peer.getInetAddress()); return false; } for (Sha256Hash hash : fetchInvDataMsg.getHashList()) { long blockNum = new BlockId(hash).getNum(); - long minBlockNum = peer.getLastSyncBlockId().getNum() - 2 * NodeConstant.SYNC_FETCH_BATCH_NUM; - if (blockNum < minBlockNum){ - logger.warn("Check FetchInvDataMsg failed: Peer {} blockNum {} lt minBlockNum {}", peer.getInetAddress(), blockNum, minBlockNum); + long minBlockNum = + peer.getLastSyncBlockId().getNum() - 2 * NodeConstant.SYNC_FETCH_BATCH_NUM; + if (blockNum < minBlockNum) { + logger.warn("Check FetchInvDataMsg failed: Peer {} blockNum {} lt minBlockNum {}", + peer.getInetAddress(), blockNum, minBlockNum); return false; } - if (peer.getSyncBlockIdCache().getIfPresent(hash) != null){ - logger.warn("Check FetchInvDataMsg failed: Peer {} blockNum {} hash {} is exist", peer.getInetAddress(), blockNum, hash); + if (peer.getSyncBlockIdCache().getIfPresent(hash) != null) { + logger.warn("Check FetchInvDataMsg failed: Peer {} blockNum {} hash {} is exist", + peer.getInetAddress(), blockNum, hash); return false; } peer.getSyncBlockIdCache().put(hash, 1); @@ -996,7 +1011,7 @@ private boolean checkFetchInvDataMsg(PeerConnection peer, FetchInvDataMessage fe private void onHandleFetchDataMessage(PeerConnection peer, FetchInvDataMessage fetchInvDataMsg) { - if (!checkFetchInvDataMsg(peer, fetchInvDataMsg)){ + if (!checkFetchInvDataMsg(peer, fetchInvDataMsg)) { disconnectPeer(peer, ReasonCode.BAD_PROTOCOL); return; } @@ -1033,7 +1048,8 @@ private void onHandleFetchDataMessage(PeerConnection peer, FetchInvDataMessage f peer.sendMessage(msg); } else { transactions.add(((TransactionMessage) msg).getTransactionCapsule().getInstance()); - size += ((TransactionMessage) msg).getTransactionCapsule().getInstance().getSerializedSize(); + size += ((TransactionMessage) msg).getTransactionCapsule().getInstance() + .getSerializedSize(); if (transactions.size() % maxTrxsCnt == 0 || size > maxTrxsSize) { peer.sendMessage(new TransactionsMessage(transactions)); transactions = Lists.newArrayList(); diff --git a/src/main/java/org/tron/program/SolidityNode.java b/src/main/java/org/tron/program/SolidityNode.java index 8100d8d2146..60f98b8f476 100644 --- a/src/main/java/org/tron/program/SolidityNode.java +++ b/src/main/java/org/tron/program/SolidityNode.java @@ -32,6 +32,7 @@ import org.tron.core.exception.ReceiptException; import org.tron.core.exception.TaposException; import org.tron.core.exception.TooBigTransactionException; +import org.tron.core.exception.TooBigTransactionResultException; import org.tron.core.exception.TransactionExpirationException; import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.UnLinkedBlockException; @@ -137,6 +138,8 @@ private void syncSolidityBlock() throws BadBlockException { throw new BadBlockException("dup exception"); } catch (TooBigTransactionException e) { throw new BadBlockException("too big exception"); + } catch (TooBigTransactionResultException e) { + throw new BadBlockException("too big exception result"); } catch (TransactionExpirationException e) { throw new BadBlockException("expiration exception"); } catch (BadNumberBlockException e) { diff --git a/src/test/java/org/tron/core/BandwidthProcessorTest.java b/src/test/java/org/tron/core/BandwidthProcessorTest.java index 611af7d88cf..95ff95eb625 100755 --- a/src/test/java/org/tron/core/BandwidthProcessorTest.java +++ b/src/test/java/org/tron/core/BandwidthProcessorTest.java @@ -182,10 +182,13 @@ public void testFree() throws Exception { AccountCapsule ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(122L, ownerCapsuleNew.getFreeNetUsage()); + Assert.assertEquals(122L + (dbManager.getDynamicPropertiesStore().supportVM() + ? Constant.MAX_RESULT_SIZE_IN_TX : 0), + ownerCapsuleNew.getFreeNetUsage()); Assert.assertEquals(508882612L, ownerCapsuleNew.getLatestConsumeFreeTime());//slot Assert.assertEquals(1526647838000L, ownerCapsuleNew.getLatestOperationTime()); - Assert.assertEquals(122L, dbManager.getDynamicPropertiesStore().getPublicNetUsage()); + Assert.assertEquals(122L + (dbManager.getDynamicPropertiesStore().supportVM() ? Constant.MAX_RESULT_SIZE_IN_TX : 0), + dbManager.getDynamicPropertiesStore().getPublicNetUsage()); Assert.assertEquals(508882612L, dbManager.getDynamicPropertiesStore().getPublicNetTime()); Assert.assertEquals(0L, ret.getFee()); @@ -195,11 +198,15 @@ public void testFree() throws Exception { ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(61L + 122, ownerCapsuleNew.getFreeNetUsage()); + Assert.assertEquals(61L + 122 + (dbManager.getDynamicPropertiesStore().supportVM() ? + Constant.MAX_RESULT_SIZE_IN_TX / 2 * 3 : 0), + ownerCapsuleNew.getFreeNetUsage()); Assert.assertEquals(508897012L, ownerCapsuleNew.getLatestConsumeFreeTime()); // 508882612L + 28800L/2 Assert.assertEquals(1526691038000L, ownerCapsuleNew.getLatestOperationTime()); - Assert.assertEquals(61L + 122L, dbManager.getDynamicPropertiesStore().getPublicNetUsage()); + Assert.assertEquals(61L + 122L + (dbManager.getDynamicPropertiesStore().supportVM() ? + Constant.MAX_RESULT_SIZE_IN_TX / 2 * 3 : 0), + dbManager.getDynamicPropertiesStore().getPublicNetUsage()); Assert.assertEquals(508897012L, dbManager.getDynamicPropertiesStore().getPublicNetTime()); Assert.assertEquals(0L, ret.getFee()); } @@ -231,11 +238,13 @@ public void testConsumeAssetAccount() throws Exception { AccountCapsule assetCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(ASSET_ADDRESS)); - Assert.assertEquals(122L, assetCapsuleNew.getNetUsage()); + Assert.assertEquals(122L + (dbManager.getDynamicPropertiesStore().supportVM() ? Constant.MAX_RESULT_SIZE_IN_TX : 0), + assetCapsuleNew.getNetUsage()); Assert.assertEquals(508882612L, assetCapsuleNew.getLatestConsumeTime()); Assert.assertEquals(1526647838000L, ownerCapsuleNew.getLatestOperationTime()); Assert.assertEquals(508882612L, ownerCapsuleNew.getLatestAssetOperationTime(ASSET_NAME)); - Assert.assertEquals(122L, ownerCapsuleNew.getFreeAssetNetUsage(ASSET_NAME)); + Assert.assertEquals(122L + (dbManager.getDynamicPropertiesStore().supportVM() ? Constant.MAX_RESULT_SIZE_IN_TX : 0), + ownerCapsuleNew.getFreeAssetNetUsage(ASSET_NAME)); Assert.assertEquals(0L, ret.getFee()); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1526691038000L); // + 12h @@ -247,11 +256,13 @@ public void testConsumeAssetAccount() throws Exception { assetCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(ASSET_ADDRESS)); - Assert.assertEquals(61L + 122L, assetCapsuleNew.getNetUsage()); + Assert.assertEquals(61L + 122L + (dbManager.getDynamicPropertiesStore().supportVM() ? Constant.MAX_RESULT_SIZE_IN_TX / 2 * 3 : 0), + assetCapsuleNew.getNetUsage()); Assert.assertEquals(508897012L, assetCapsuleNew.getLatestConsumeTime()); Assert.assertEquals(1526691038000L, ownerCapsuleNew.getLatestOperationTime()); Assert.assertEquals(508897012L, ownerCapsuleNew.getLatestAssetOperationTime(ASSET_NAME)); - Assert.assertEquals(61L + 122L, ownerCapsuleNew.getFreeAssetNetUsage(ASSET_NAME)); + Assert.assertEquals(61L + 122L + (dbManager.getDynamicPropertiesStore().supportVM() ? Constant.MAX_RESULT_SIZE_IN_TX / 2 * 3 : 0), + ownerCapsuleNew.getFreeAssetNetUsage(ASSET_NAME)); Assert.assertEquals(0L, ret.getFee()); } @@ -281,7 +292,8 @@ public void testConsumeOwner() throws Exception { AccountCapsule assetCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(ASSET_ADDRESS)); - Assert.assertEquals(122L, ownerCapsuleNew.getNetUsage()); + Assert.assertEquals(122L + (dbManager.getDynamicPropertiesStore().supportVM() ? Constant.MAX_RESULT_SIZE_IN_TX : 0), + ownerCapsuleNew.getNetUsage()); Assert.assertEquals(1526647838000L, ownerCapsuleNew.getLatestOperationTime()); Assert.assertEquals(508882612L, ownerCapsuleNew.getLatestConsumeTime()); Assert.assertEquals(0L, ret.getFee()); @@ -293,7 +305,8 @@ public void testConsumeOwner() throws Exception { ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(61L + 122L, ownerCapsuleNew.getNetUsage()); + Assert.assertEquals(61L + 122L + (dbManager.getDynamicPropertiesStore().supportVM() ? Constant.MAX_RESULT_SIZE_IN_TX / 2 * 3 : 0), + ownerCapsuleNew.getNetUsage()); Assert.assertEquals(1526691038000L, ownerCapsuleNew.getLatestOperationTime()); Assert.assertEquals(508897012L, ownerCapsuleNew.getLatestConsumeTime()); Assert.assertEquals(0L, ret.getFee()); @@ -333,7 +346,9 @@ public void testUsingFee() throws Exception { AccountCapsule ownerCapsuleNew = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - long transactionFee = (122L) * dbManager.getDynamicPropertiesStore().getTransactionFee(); + long transactionFee = + (122L + (dbManager.getDynamicPropertiesStore().supportVM() ? Constant.MAX_RESULT_SIZE_IN_TX : 0)) * dbManager + .getDynamicPropertiesStore().getTransactionFee(); Assert.assertEquals(transactionFee, dbManager.getDynamicPropertiesStore().getTotalTransactionCost()); Assert.assertEquals( diff --git a/src/test/java/org/tron/core/db/ManagerTest.java b/src/test/java/org/tron/core/db/ManagerTest.java index dfcdd0937af..1c53a762180 100755 --- a/src/test/java/org/tron/core/db/ManagerTest.java +++ b/src/test/java/org/tron/core/db/ManagerTest.java @@ -38,6 +38,7 @@ import org.tron.core.exception.ReceiptException; import org.tron.core.exception.TaposException; import org.tron.core.exception.TooBigTransactionException; +import org.tron.core.exception.TooBigTransactionResultException; import org.tron.core.exception.TransactionExpirationException; import org.tron.core.exception.TransactionTraceException; import org.tron.core.exception.UnLinkedBlockException; @@ -91,7 +92,7 @@ public void removeDb() { @Test public void setBlockReference() throws ContractExeException, UnLinkedBlockException, ValidateScheduleException, BadBlockException, - ContractValidateException, ValidateSignatureException, BadItemException, ItemNotFoundException, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, DupTransactionException, TaposException, BadNumberBlockException, NonCommonBlockException, ReceiptException, TransactionTraceException, ReceiptCheckErrException, UnsupportVMException { + ContractValidateException, ValidateSignatureException, BadItemException, ItemNotFoundException, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, DupTransactionException, TaposException, BadNumberBlockException, NonCommonBlockException, ReceiptException, TransactionTraceException, ReceiptCheckErrException, UnsupportVMException, TooBigTransactionResultException { BlockCapsule blockCapsule = new BlockCapsule( @@ -219,7 +220,7 @@ public void fork() ItemNotFoundException, HeaderNotFound, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, DupTransactionException, BadBlockException, TaposException, BadNumberBlockException, NonCommonBlockException, - TransactionTraceException, ReceiptCheckErrException, UnsupportVMException { + TransactionTraceException, ReceiptCheckErrException, UnsupportVMException, TooBigTransactionResultException { Args.setParam(new String[]{"--witness"}, Constant.TEST_CONF); long size = dbManager.getBlockStore().size(); System.out.print("block store size:" + size + "\n"); @@ -288,7 +289,7 @@ public void doNotSwitch() TransactionExpirationException, TooBigTransactionException, DupTransactionException, BadBlockException, TaposException, BadNumberBlockException, NonCommonBlockException, TransactionTraceException, - ReceiptCheckErrException, UnsupportVMException { + ReceiptCheckErrException, UnsupportVMException, TooBigTransactionResultException { Args.setParam(new String[]{"--witness"}, Constant.TEST_CONF); long size = dbManager.getBlockStore().size(); System.out.print("block store size:" + size + "\n"); @@ -383,7 +384,7 @@ public void switchBack() ItemNotFoundException, HeaderNotFound, AccountResourceInsufficientException, TransactionExpirationException, TooBigTransactionException, DupTransactionException, BadBlockException, TaposException, BadNumberBlockException, NonCommonBlockException, - TransactionTraceException, ReceiptCheckErrException, UnsupportVMException { + TransactionTraceException, ReceiptCheckErrException, UnsupportVMException, TooBigTransactionResultException { Args.setParam(new String[]{"--witness"}, Constant.TEST_CONF); long size = dbManager.getBlockStore().size(); System.out.print("block store size:" + size + "\n");